Most cloud overspend isn't dramatic. There's no runaway autoscaler, no leaked credential spinning up GPU fleets. It's quieter than that: a fleet of development, staging, QA and demo clusters humming along at 3 a.m. on a Sunday, fully provisioned, fully billed, and doing precisely nothing. This is the hidden cost of idle Kubernetes — and for most organisations it's one of the largest, least-governed line items on the cloud invoice.
The good news for anyone holding a cloud P&L: it's also one of the easiest to fix. Below is the evidence, the economics, and a worked example of how a mid-sized engineering organisation cut roughly £4,500 a month from its non-production bill by doing one unglamorous thing — putting clusters to sleep when nobody's using them.
Why idle clusters cost so much — and stay hidden
Kubernetes was built to keep applications available, not to keep accountants happy. Engineers set resource requests — hard reservations the scheduler honours whether or not the workload uses them — and they set them conservatively, because an outage triggers a post-mortem while waste shows up anonymised on a monthly bill. The rational individual choice is to over-provision and stay safe. Multiplied across hundreds of services and several environments, those safe choices become a structural billing problem disguised as a configuration one.
The benchmarks are stark. Analysis of thousands of production clusters across AWS, Google Cloud and Azure found average CPU utilisation sitting at roughly 10% and memory near 23% — meaning the majority of provisioned, paid-for capacity never does useful work. Independent industry estimates put idle or unallocated spend at 35–50% of total cluster cost, and BCG has estimated that up to 30% of all cloud spend is wasted on over-provisioned or idle resources.
Idle cost has two distinct faces, and conflating them is why the problem rarely gets fixed:
- Node-level idle — you're paying for nodes (EC2/GCE/Azure VMs) whose capacity no pod is consuming. This is an infrastructure-team problem and is straightforward to measure: node cost minus the cost of pods running on it.
- Workload-level over-provisioning — the pods are running and capacity is reserved, but actual usage is a fraction of the request. This belongs to the developers who set the requests.
Roll both into a single "Kubernetes idle" figure and you get a metric nobody owns — and a metric nobody owns is a metric nobody fixes.
The single highest-ROI fix: auto-sleep for non-production
Production needs to be available around the clock. Development, staging, QA, UAT and demo environments almost never do. They typically sit idle 12–16 hours of every working day and the entire weekend — yet most run 24/7 because no single team owns non-prod infrastructure, so nobody is incentivised to switch it off.
Do the arithmetic on a normal working week. If an environment is genuinely needed only ~50 hours a week (10 hours × 5 days), it's idle for the other ~118 hours — about 70% of the time. Sleeping it overnight and at weekends therefore removes the majority of its cost. Published benchmarks consistently land in the same range: scheduled scale-down of non-prod node pools delivers 50–70% cost reduction on those environments, with no application code changes.
How auto-sleep actually works
"Scaling deployments to zero" is necessary but not sufficient. If you only scale pods down, the StatefulSets, DaemonSets and — crucially — the worker nodes keep running, and the cloud provider keeps billing for the VMs. A real auto-sleep policy has to reach the node layer:
- Schedule the workloads down — a CronJob (or an operator such as the open-source kube-downscaler or KEDA Cron scaler) scales deployments to zero at, say, 19:00 and back up at 07:00 on weekdays only.
- Let the nodes follow — a node autoscaler such as Karpenter or Cluster Autoscaler, configured to consolidate and terminate empty nodes, removes the underlying VMs once the pods are gone. This is where the actual money is saved.
- Provide a wake path — on-demand wake (via ingress traffic, a pull-request event, or a one-click override) so engineers working late aren't blocked. Friction is the enemy: a policy people route around saves nothing.
- Govern the overrides — track which environments are kept alive against policy, so finance can trace the cost and platform teams can see configuration drift.
Going further: provision non-production on-demand
Auto-sleep is the pragmatic first move because it works on the estate you already have. But it accepts a hidden premise: that those non-production environments should exist as standing infrastructure at all. Sleeping is still paying — for orphaned volumes, load balancers, control-plane fees and the operational drag of clusters that linger for weeks. The more advanced posture flips the default from always-on, sometimes-asleep to nothing-on, created-on-demand.
In this model an environment doesn't sit waiting to be used. It is created the moment it's needed — when a pull request opens, a QA run is triggered, or an engineer requests a sandbox — and destroyed automatically when the work is done or after a short idle timeout. Each environment becomes ephemeral, single-purpose and traceable to the change that spawned it. The most mature version is the preview environment: every PR gets its own short-lived stack, exercised by automated tests and reviewers, then torn down on merge.
How this works with Infrastructure-as-Code
On-demand provisioning is only safe and repeatable if the entire environment is codified. This is where Infrastructure-as-Code (IaC) stops being a convenience and becomes the load-bearing dependency. The cluster, node pools, networking, namespaces, application manifests and seed data all have to be reproducible from a definition in version control — because you are no longer maintaining a long-lived environment, you are rebuilding it from scratch, on every request, identically.
- Declarative everything. Terraform, OpenTofu, Pulumi or CloudFormation describe the infrastructure; Helm, Kustomize or raw manifests describe the workloads. The environment is the sum of those definitions plus a handful of parameters (branch name, namespace, sizing tier).
- GitOps as the trigger. A tool such as Argo CD or Flux watches the repository and reconciles desired state into a real environment. A merged or opened branch becomes the event that materialises (or removes) an environment — no manual
kubectlrequired. - Disposability by design. Because creation is automated and tested, teams stop being precious about environments. An environment that is trivial to recreate is one you can destroy without fear — which is precisely what makes the cost model work.
- Ephemeral data and config. Seed databases from fixtures or anonymised snapshots, inject secrets from a vault at provision time, and accept that state is transient. This is the hardest part and the main reason teams stall before reaching full on-demand maturity.
Done well, IaC turns "an environment" from a pet you feed indefinitely into cattle you spin up and cull on demand — and it gives you a clean audit trail of exactly what existed, when, and why.
How it changes the maths and the ROI
Auto-sleep removes the off-hours portion of the bill. On-demand provisioning attacks a different variable entirely: it removes the idle-but-awake hours that auto-sleep can't, because the environment simply doesn't exist when no one is using it. The shift is from a fixed cost you discount to a variable cost you only incur on consumption.
Consider the same composite organisation. Under auto-sleep, a non-prod estate runs roughly 50 hours a week and you've cut ~55% of the bill. Under true on-demand provisioning, an environment exists only for the hours work is actively happening inside it — often a few hours per PR or test run, not a fixed 10-hour weekday window. In practice teams report this pushing total non-prod reduction from the 50–70% range of auto-sleep towards 80–90%, because the long tail of "environment that's technically up but nobody touched today" disappears.
The ROI calculation changes shape, too. Auto-sleep's return is a straightforward percentage off a known bill. On-demand's return has three components worth modelling separately:
- Direct compute savings — the 80–90% reduction above, applied to the non-prod run-rate. On a £100,000/year estate that is roughly £80,000–£90,000 a year, versus ~£55,000 from auto-sleep alone.
- Eliminated standing overhead — control-plane fees, idle persistent volumes, unused load balancers and stale snapshots that auto-sleep leaves running. These are small per item but compound across a large estate.
- An upfront engineering investment — the cost auto-sleep mostly avoids. Codifying environments, building the GitOps pipeline and solving ephemeral data is real work, typically weeks to a few months of platform-team effort. This is the denominator in the ROI, and it's why on-demand is the second move, not the first.
The honest framing for a CTO: auto-sleep is high return for near-zero investment, so do it now. On-demand provisioning is higher return for a real, front-loaded investment — and it pays back not only in compute but in faster, more reliable testing and a non-prod estate that can't quietly sprawl. Sequence them. Capture the easy 55% with auto-sleep this quarter, then reinvest part of the saving into the IaC and GitOps foundation that takes you to 80–90%.
A worked example: ~£4,500 a month, recovered
Consider a fairly typical mid-sized engineering organisation — a composite drawn from the published benchmarks rather than a single named customer. It runs a non-production Kubernetes estate (dev, staging, QA and a handful of demo environments) costing roughly £100,000 a year, or about £8,300 a month, all of it billed 24/7.
The platform team introduces a single policy: all non-prod namespaces sleep between 19:00 and 07:00 on weekdays and all weekend, with Karpenter consolidating the freed nodes and an ingress-based wake for after-hours use. Production is untouched.
Those environments are now switched off for roughly 55–60% of each month. Applying a conservative ~55% reduction to the off-hours portion of the bill yields a saving of around £4,500–£4,600 every month — close to £55,000 a year — from one configuration change, with no new headcount and no impact on production reliability.
A note on honesty: these figures are modelled from the public benchmarks cited below, not a single audited customer engagement — your mileage depends on how much of your estate is non-prod and how aggressively it's scheduled. The direction of travel, however, is well documented and consistent across vendors and independent reports.
What this means for a CTO
Three things make auto-sleep unusually attractive as a first move in a cost programme:
- It's low-risk. It touches only non-production. There is no production performance trade-off to weigh, unlike aggressive rightsizing of stateful workloads.
- It's fast. Open-source operators install in minutes; the savings start from day one and are trivially measurable on the next invoice.
- It's a wedge. It establishes the cultural principle that efficiency is a first-class engineering metric — the foundation everything else (rightsizing, Spot adoption, commitment management) builds on.
There's a sustainability dividend, too: capacity you switch off is energy you don't draw. For organisations with carbon-reporting obligations, off-hours scheduling is one of the cleaner stories to tell — lower bill and lower footprint from the same action.
A pragmatic 30-day plan
- Measure. Pull 30 days of node and pod utilisation (Kubecost/OpenCost, Prometheus, or native CloudWatch/Cloud Monitoring/Azure Monitor) and separate node-level idle from workload over-provisioning so each has an owner.
- Pick the easy win. Identify every non-production environment running 24/7. This is almost always the largest unowned cost.
- Pilot one policy. Apply an off-hours sleep schedule to a single non-prod namespace, paired with node consolidation and an on-demand wake path. Verify the saving on the bill.
- Roll out and govern. Extend across non-prod, give developers a frictionless override, and report the recovered spend to finance monthly.
The bottom line: idle Kubernetes is the cloud's most expensive open secret. The clusters that quietly bill you at 3 a.m. on a Sunday are doing no work — and the fix is to let them sleep. Few infrastructure decisions offer this much saving for this little risk.