Kubernetes Cost Optimisation: Where the Money Is Usually Hiding
Requests, not usage, decide your bill
Kubernetes schedules on requested resources, so a pod requesting four cores and using half of one still occupies four cores of scheduling capacity. This is the single largest source of waste in almost every cluster we review, and it originates innocently: someone copied a manifest, or set generous requests during an incident and never revisited them. Pull actual utilisation over a few weeks, set requests near the observed 95th percentile with headroom, and keep limits sensible. This alone commonly recovers a third of the bill.
Scale the nodes as well as the pods
Horizontal pod autoscaling without cluster autoscaling means you add pods onto nodes you were already paying for, and never give nodes back. Enable node autoscaling, allow consolidation so workloads pack onto fewer machines, and make sure pod disruption budgets permit that consolidation to actually happen — an overly strict budget silently blocks scale-down and nobody notices because nothing breaks. Check whether your cluster has ever scaled down; a surprising number never have.
Use cheaper capacity for interruptible work
Spot and preemptible instances cost a fraction of on-demand and suit batch jobs, CI runners, dev environments and stateless services with several replicas. The requirement is that workloads tolerate a node vanishing with short notice, which is a property you should want anyway. A common split is a small on-demand baseline for stateful and latency-critical components, with everything else on interruptible capacity spread across instance types to reduce the chance of simultaneous reclamation.
Non-production environments run all night for nobody
Development, staging and QA clusters typically serve a team in one or two time zones for eight hours a day, five days a week — that is roughly a quarter of the week. Scheduled scale-down outside working hours is straightforward and cuts non-production spend substantially. Add automatic expiry on ephemeral preview environments, because the ones created per pull request accumulate quietly and nobody ever deletes them manually.
Storage, data transfer and forgotten resources
Unattached volumes from deleted pods, old snapshots, oversized persistent volumes provisioned at peak-load guesses, load balancers left behind by removed services, and cross-zone traffic between chatty services all add up. Cross-zone data transfer in particular surprises people, and topology-aware routing can cut it materially. Run a monthly sweep for orphaned resources; it takes an hour and it always finds something.
Make costs visible to the teams that create them
Central platform teams cannot optimise workloads they do not own. Attribute cost by namespace and team, publish it monthly, and give each team its own number to manage. Visibility changes behaviour more reliably than policy does — engineers who can see that their service costs more than the rest of the platform combined will usually fix it without being asked. Alert on week-over-week increases so you catch a change in days rather than in the invoice.
Have a project that needs this kind of thinking?
Let's talk through what you're building — free consultation, no commitment.
Get in Touch