GKE cost, and why Autopilot moves the waste rather than removing it

Standard bills for nodes you provision, Autopilot bills for pod resources you request. Both are dominated by the same number, and it is the gap between what pods ask for and what they use.

Two teams migrate from Standard to Autopilot for cost reasons. One sees the bill fall by a third. The other sees it rise. The workloads are similar and both outcomes are predictable from a single measurement neither team took beforehand.

Under Standard, you pay for the nodes. A pod requesting four cores and using half of one is waste you can see as low node utilisation, and it is tolerable because the node is already paid for. Under Autopilot, you pay for what the pod requests. The same pod now bills for four cores directly, and the waste stops being hidden and starts being itemised.

Autopilot does not fix over-requesting. It prices it.

Measure the ratio before choosing anything

The number that decides both the platform choice and every optimisation after it is the ratio of requested CPU and memory to actually used CPU and memory, per namespace.

Get it from managed Prometheus, comparing kube_pod_container_resource_requests against real consumption, or from the recommendations surfaced by the vertical pod autoscaler. Above 3x you are buying three units of capacity to run one unit of work. Below 1.5x you are in reasonable shape.

If that ratio is high, Autopilot will be expensive, because it charges directly for the thing you are getting wrong. Fix the requests first, then choose the platform. The decision itself, beyond cost, is in GKE Autopilot or Standard.

The Standard levers

Requests set from observed usage. Requests belong near the p95 of real consumption. The vertical pod autoscaler in recommendation mode produces the numbers without acting on them; run it a fortnight and apply the output by hand. Set memory limits, because the alternative is a node-wide out-of-memory event, and be sparing with CPU limits, which throttle at p99 while the node sits idle.

Node auto-provisioning rather than hand-sized pools. The cluster autoscaler scales pools you defined in advance, so bin packing is capped by the machine types you guessed at. Node auto-provisioning creates pools sized to the pending workload. Combine it with the optimise-utilisation autoscaling profile, which consolidates more aggressively at the cost of slightly more disruption.

Spot VMs for what tolerates them. Stateless, replicated, restart-tolerant workloads on a Spot pool with a diversified machine type list, and an on-demand core for anything control-plane-adjacent. The discount is deep. What hurts teams is a single-replica stateful service on Spot.

Custom machine types. A genuine advantage of this platform: if your workloads are memory-heavy relative to CPU, a custom shape avoids paying for cores you will not use. Most estates never try this.

Committed use discounts against the corrected baseline, never before it. The order and the reasoning are in committed use discounts in Google Cloud.

The Autopilot levers are different

Under Autopilot, node-level optimisation disappears and everything becomes about the pod spec.

Requests are the bill. Nothing else. A downward revision of requests translates directly into money, which is a clearer feedback loop than Standard ever provides.

Compute classes matter. The general-purpose class is the default and there are classes for scale-out, balanced and accelerator workloads with different price and performance characteristics. Choosing deliberately rather than defaulting is worth real money on a large cluster.

Spot pods are available and are the single largest saving for tolerant workloads.

Minimums and rounding. Pods have minimum resource amounts and requests are rounded, so very small pods are less efficient than their spec suggests. A deployment of forty tiny sidecar-like pods can cost more than the arithmetic implies.

DaemonSets are billed too, and you have less control over the node count they land on.

The honest framing: Autopilot removes node management work and charges a premium per unit of pod resource. It wins when your requests are accurate and your cluster utilisation under Standard would have been poor. It loses when you were already packing nodes well.

The costs that are neither nodes nor pods

  • The cluster management fee. Charged per cluster per hour above the free allowance. Four small clusters where one with namespaces would do is pure overhead, and it is the argument for several teams on one cluster.
  • Cross-zone traffic. In a regional cluster with topology-unaware services, most pod-to-pod traffic crosses a zone boundary and is billed. Topology-aware routing keeps traffic local where it can, and on chatty microservice estates the difference is a genuine line item.
  • Load balancers and external addresses, one per exposed service unless you share an ingress.
  • Logging and monitoring. Container logs from every namespace at default settings are frequently a larger line than a node pool. Exclusion filters at the sink are the highest-return control, as set out in Cloud Logging and Cloud Storage costs.
  • Orphaned persistent disks from claims deleted with a retain policy.

Scale to zero properly

The horizontal pod autoscaler scales on CPU and memory, which is the wrong signal for most of what needs scaling. KEDA scales on queue depth, Pub/Sub backlog or a Prometheus query, and it scales to zero. A worker deployment running two replicas overnight against an empty subscription is a small, permanent, entirely avoidable cost.

For genuinely bursty request-driven workloads, the honest question is whether this belongs in a cluster at all, which is the comparison in Cloud Run or GKE.

Over-provisioning deliberately

One counterintuitive practice worth knowing. If your problem is that scaling up takes too long, the usual fix is to keep spare nodes, which is expensive and invisible.

The better version is balloon pods: low-priority placeholder pods that reserve capacity and get evicted immediately when a real workload needs the space. You get fast scheduling without paying for idle nodes you cannot account for, and the cost is explicit and tunable rather than hidden in a node pool minimum.

What to do this week

Compute the requests-to-usage ratio for your three largest namespaces. If it is above 2.5x, that is your answer regardless of which platform you run, and the vertical pod autoscaler in recommendation mode will hand you the corrected numbers within a fortnight. Do not migrate to Autopilot to fix it; migrate after fixing it, if the numbers still favour it. We work through this in the cost phase of a cloud engagement.

ConsultorIA

Want this done on your cloud?

A ten-day read-only assessment is free, and Skyline lets you see your estate on a map before you write to us.

Related articles

Modules people reuse instead of copying

The two failures are a module that wraps one resource and adds nothing, and a module that does everything and nobody dares change. A minimal interface, safe defaults and honest versioning are what separate them.