Kubernetes cost optimisation checklist
Guides · 25 September 2026 · 8 minute read
Kubernetes cost optimisation starts from an awkward fact: the cloud bills you for nodes, but you schedule pods. The gap between what pods ask for and what nodes provide is where most of the money goes, and no single dashboard shows it. This checklist walks through the gap in the order that usually pays back fastest, whether you run EKS, AKS or GKE.
1. Know what you are actually paying for
- Node hours, not pod hours. The bill is instance-hours (plus storage, load balancers and data transfer). A cluster at 20% CPU utilisation is paying for 80% air. Get utilisation per node group before touching anything else.
- Requests versus usage. The scheduler places pods by requests, not by what they use. A pod requesting 2 CPU and using 0.2 reserves ten times what it needs, and the node it blocks still bills. Compare requested to used, per workload, over at least two weeks.
- Cost per namespace. Label workloads by team or product and allocate node cost by requests. Without this, nobody owns the number, and unowned numbers do not fall.
2. Right-size requests and limits
- Set CPU requests from observed p95 usage, with headroom, rather than from a template copied across every deployment.
- Set memory requests from observed peak, since memory is not compressible and an under-request is an OOM kill. Memory limits should match requests unless you have a reason.
- Use the Vertical Pod Autoscaler in recommendation mode to get numbers, even if you never let it apply them.
- Watch for CPU limits that throttle latency-sensitive services. Removing a limit can be a cost and performance win when requests are set honestly.
3. Fit the nodes to the pods
- Instance families. Memory-heavy workloads on general-purpose nodes waste CPU; the reverse wastes memory. Match node groups to the workloads they host.
- Arm. Graviton (AWS), Ampere (Azure) and Tau T2A (Google) instances are cheaper for the same work when your images are multi-arch. Most are, or can be, with one build change.
- Spot for stateless work. Anything that tolerates an interruption (batch, queue consumers, most web replicas behind a load balancer) can run on Spot at a large discount. Keep the control plane and stateful sets on demand.
- Consolidation. Karpenter on AWS, or the cluster autoscaler elsewhere, should be allowed to drain under-used nodes. If bin-packing is poor, the settings are usually the reason: pod disruption budgets that forbid everything, or a scale-down delay of hours.
4. Scale to demand, including to zero
- Horizontal Pod Autoscaler on the services with real traffic curves, with a minimum replica count that reflects actual quiet-hour load.
- Non-production clusters scaled to zero outside working hours. This alone is often the largest single saving, and the least controversial.
- Cron jobs and batch on their own node group, so their bursts do not size the always-on pool.
5. Storage and network
- Persistent volumes outlive the pods that created them. List volumes with no claim, and claims with no pod.
- Cross-availability-zone traffic between pods is billed. Topology-aware routing keeps chatty services in one zone where that is safe.
- Egress through NAT gateways is billed per gigabyte. Image pulls, package downloads and calls to cloud APIs can all go through private endpoints instead.
- Load balancers: one per service adds up. An ingress controller sharing a single load balancer is usually the cheaper shape.
6. Commit to the baseline
Once the cluster is right-sized, the always-on part of it is predictable. Cover that baseline with Savings Plans, reservations or committed-use discounts, and leave the variable part on demand or Spot. Committing before right-sizing locks in the waste.
7. Keep it that way
- Resource quotas and limit ranges per namespace, so a new deployment cannot request the world by default.
- A cost report per team, monthly, from the labels in step 1.
- Anomaly alerts on node count and on bill, with a threshold that someone will actually act on.
The checklist
- Utilisation per node group measured over two weeks
- Requests compared with usage for every workload
- Cost allocated by namespace or team
- Requests re-set from observed usage; VPA recommendations reviewed
- Node groups matched to workload shape; Arm and Spot evaluated
- Autoscaler allowed to consolidate; disruption budgets sane
- Non-production scaled to zero out of hours
- Orphaned volumes, cross-zone traffic and NAT egress checked
- Baseline covered by commitments, after right-sizing
- Quotas, reports and alerts in place
If you would rather have someone run this against your clusters with read-only access and hand you the evidence, that is what our FinOps & Cost OptimisationAWS Cost Optimisation engagement does. It starts with a free cloud cost audit.