Skip to main content
idle · gcp

GKE Idle Load Balancer

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

GKE load balancers are declared idle only when every harvested traffic axis (up to 9 covering requests, connections, ingress, and egress) stays below the 0.05 floor on both average and peak with 30 or more days of coverage. Savings equal the forwarding rule's full fixed fee.

Signal and threshold

How ZopNight evaluates GKE Idle Load Balancer.
Field Value
Rule IDsRC-122
Categoryidle
Severitymedium
Metricnone — pure configuration read
Sourcegke_idle_lb.go

Traffic evidence from forwarding rule metrics

none beyond resource.UID/Type; pricing comes from the cost engine (r.pricing[uid]), traffic evidence comes from Cloud Monitoring via the aggregator’s forwarding_rule_name-dimensioned harvest (present on all GCP LB monitored-resource types: HTTP(S), L3/L4 passthrough, TCP/SSL proxy). (GCPGlobalIdleLBRule, resource type gcp-global-lb) via an unexported (*GKEIdleLBRule).evaluate(resource, ruleID) helper parameterized by RuleID. Each rule’s exported Evaluate() passes its own rule ID explicitly (Go embedding is not virtual dispatch, so a shared method cannot read r.ID() and expect the embedder’s override). gcp-global-lb harvests only a subset of the 9 axes (LBHTTPSRequestCount, LBProxyNewConnections, plus HTTPS bytes/latency, per the aggregator’s gcp-global-lb spec); the rule evaluates whichever declared axes are present for the UID and abstains when none is.

The full forwarding rule fee comes back

concrete-or-abstain (never fabricated/$0). An LB is idle only when every declared traffic axis present for it is below the 0.05 floor on both average and peak (Bug-1: reads each axis by name off the nested metrics view, never a first-wins bare-UID metric) and the representative axis has >= 30 days of measured coverage. Fires only when pricing is known; the saving is the full current forwarding-rule fixed fee (SavingsUSD = cost, OptimizedCostUSD = 0). Abstains (returns nil) when no traffic axis was harvested, any present axis is above the floor, coverage is short, or pricing is absent. Egress (both L3 external/internal) and TCP/SSL-proxy open-connections/ingress/egress axes are required in addition to ingress/new-connections/request-count: a passthrough LB fronting a download-heavy backend has near-zero application-stream ingress while egress is large, and a proxy LB fronting long-lived connections (DB proxy, MQTT, websockets) has near-zero new connections while open connections and bytes stay high. Either gap alone would misclassify an actively-serving LB as idle.

Deleting the forwarding rule

  1. Verify no traffic is routed through this load balancer in GCP Cloud Monitoring
  2. Check if any backend services or instance groups are attached
  3. Confirm with the owning team that the load balancer is no longer needed
  4. Delete the forwarding rule and associated backend configuration to stop charges

Why egress and open connections also count

LBHTTPSRequestCount, LBExternalIngressBytes, LBInternalIngressBytes, LBProxyNewConnections, LBExternalEgressBytes, LBInternalEgressBytes, LBProxyOpenConnections, LBProxyEgressBytes, LBProxyIngressBytes (loadbalancing.googleapis.com, 30d, 0.05 floor per axis, checked on both the windowed average AND the full-series peak; was exact ==0 pre-fix)

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·