Kubernetes Cost Optimization in 2026: 8% CPU Use and What Fixes It

Oct 20, 2026 · 12 min · Ajay Kumar

Every Kubernetes cost review I have sat in starts with the same chart: a cluster bill going up and to the right, and a utilisation graph lying flat along the bottom. The interesting part is never the waste itself, which everyone already suspects, but why it survives a decade of autoscalers, dashboards and FinOps teams. This post walks through what the 2026 data says about Kubernetes cost optimization, why requests rather than usage set the bill, where OpenCost and IBM's Kubecost stand after the acquisition, what Karpenter's consolidation actually does in version 1.15, and how far spot instances and Arm nodes get you. It is the cluster-level companion to my FinOps for AI post, which covers the token side of the bill.

How much Kubernetes spend is wasted in 2026?

The most-quoted number this year comes from Cast AI's third annual State of Kubernetes Optimization report, published 21 April 2026. It measured "tens of thousands" of production clusters on AWS, GCP and Azure before Cast AI's automation was switched on, covering calendar 2025 plus GPU data through April 2026. Average CPU utilisation was 8 percent, down from 10 percent the year before. Memory was 20 percent, down from 23. CPU overprovisioning rose from 40 to 69 percent, memory overprovisioning sat at 79 percent, and average GPU utilisation was 5 percent.

The other large dataset is Datadog's State of Cloud Costs 2024, covering May 2023 to April 2024. It found that about 83 percent of container costs were associated with idle resources, and split that into roughly 54 points of cluster idle (nodes nobody requested) and 29 points of workload idle (requests nobody used). Containers were about 35 percent of EC2 compute spend in that sample.

Two caveats. Both companies sell cost tooling, so neither has a reason to find your cluster efficient, and Cast AI's sample is by construction clusters whose owners were shopping for optimisation. Still, the direction matches every cluster I have looked at: the scheduler is full and the CPUs are idle.

Used versus reserved: Kubernetes efficiency in vendor fleet data (percent) CPU utilisation (Cast AI) 8 Memory utilisation (Cast AI) 20 GPU utilisation (Cast AI) 5 CPU overprovisioning (Cast AI) 69 Memory overprovisioning (Cast AI) 79 Container cost idle (Datadog) 83 0 25 50 75 100 Green: share of capacity used. Terracotta and cream: share reserved or paid for but idle.
Cast AI figures are from its 2026 State of Kubernetes Optimization report (calendar 2025 data, pre-automation); the Datadog figure is from State of Cloud Costs 2024 (May 2023 to April 2024). Both are vendor datasets.

Why requests, not usage, set your Kubernetes bill

The scheduler places pods by their resource requests. A pod that requests 2 CPUs and uses 0.1 still removes 2 CPUs from the node's allocatable capacity, and when the next pod does not fit, the cluster autoscaler or Karpenter adds a node. Nothing in that loop looks at actual usage. So the bill follows the sum of requests, plus whatever headroom your node shapes leave stranded, and utilisation can fall while the cluster grows.

That gives two separate problems, which Datadog's split captures well:

  • Workload idle: requests larger than usage. The fix is rightsizing, which is a people and process problem before it is a tooling problem, because engineers pad requests after one OOMKill and the padded value gets copied into the Helm chart template for the next fifty services. Cast AI's report says as much about templates.
  • Cluster idle: nodes with capacity nobody requested, from fragmentation, oversized instance types, or daemonsets and system reservations on small nodes. The fix is bin-packing and consolidation at the node layer.

Fixing only one of them moves the waste rather than removing it. Shrink requests without consolidating and you get emptier nodes at the same price. Consolidate without shrinking requests and the bin-packer is packing air. If requests and limits still feel fuzzy, the requests and limits explainer is the place to start.

OpenCost vs Kubecost in 2026: what changed after IBM

You cannot rightsize what you cannot attribute, so cost allocation comes first. Two tools dominate the open end of the market and they share a codebase.

OpenCost was accepted into the CNCF on 17 June 2022 and moved to Incubating on 25 October 2024. It allocates cluster cost to namespaces, deployments, labels and pods using cloud provider pricing, and exposes it through an API, a UI and Prometheus metrics. The current line is v1.121.3, released 16 September 2026. The v1.121.0 release in July added a first version of AI inference cost allocation and stopped exposing certain endpoints unless an admin token is set, which is worth knowing if you scrape it from outside the cluster.

Kubecost, the commercial product OpenCost came out of, was acquired by IBM in September 2024 and folded into IBM's FinOps suite alongside Apptio Cloudability and Turbonomic. IBM Kubecost 3.0, announced 30 September 2025, is a substantial rework: ClickHouse replaces DuckDB as the store, a unified agent removes the hard Prometheus dependency, the free tier now covers non-Kubernetes cloud costs, and automated container request sizing is available on the free tier up to 250 cores. IBM's own post describes the free-tier spend gate in two ways that do not obviously agree, so check the current terms before you plan around them.

Tool or lever What it attacks Constraint to know Source
OpenCost v1.121 Attribution (who spends what) Allocation only, no automated action CNCF, release
IBM Kubecost 3.0 Attribution plus request and node sizing Automated sizing free up to 250 cores IBM/Apptio
In-place pod resize + VPA Workload idle GA in Kubernetes 1.35; VPA in-place mode Kubernetes blog
Karpenter consolidation Cluster idle Default budget 10% of nodes; PDBs respected Karpenter docs
Spot capacity Price per node-hour Up to 90% off, two-minute warning AWS Spot, AWS docs
Graviton (arm64) Price per node-hour Multi-arch images required AWS Graviton

My rule of thumb: run OpenCost (or Kubecost's free tier) for attribution and showback, and put the money you save on licences into the boring work of getting teams to look at their own namespace's number every sprint. Attribution that nobody reads is just another dashboard.

Rightsizing pods: VPA, in-place resize, and why once is not enough

The historic objection to the Vertical Pod Autoscaler was that applying a recommendation meant evicting the pod. That changed when in-place pod resize graduated to stable in Kubernetes 1.35 in December 2025, after alpha in 1.27 and beta in 1.33. CPU and memory requests and limits are now mutable on a running pod, often without a container restart. VPA's InPlaceOrRecreate update mode builds on it, and the current VPA 1.8.0 release (September 2026) is mostly hardening of that path, such as treating transient kubelet resize errors as deferred rather than permanent.

Cast AI's argument, which I agree with, is that rightsizing at deploy time decays. Traffic changes, a dependency gets heavier, someone adds a sidecar. A one-off rightsizing sprint gives you a good quarter and then the padding creeps back. Continuous recommendation, applied in place, with a floor and ceiling per workload, is the version that sticks. Two cautions from experience in general terms: do not let VPA and an HPA scaling on CPU fight over the same resource, and keep memory limits conservative, because a resize that lowers memory below the working set produces exactly the OOMKill that caused the padding in the first place. The autoscaling explainer covers how HPA, VPA and node autoscalers interact.

Karpenter consolidation in 1.15: the Balanced policy and disruption budgets

Karpenter is where cluster idle gets removed. It provisions nodes directly from pending pods, picking instance types to fit, and then consolidates: deleting empty nodes, or replacing several underused nodes with fewer or cheaper ones. The current release is v1.15.0, published 10 October 2026, with a v1.14.2 patch on 16 October.

The notable change this year landed in v1.14.0 in July: a third consolidation policy. The disruption docs now list three:

  • WhenEmpty removes only empty nodes, the conservative choice.
  • Balanced acts only when the cost saving outweighs the pod disruption, while still removing empty and clearly underutilised nodes.
  • WhenEmptyOrUnderutilized, the default, removes or replaces any node if the result is cheaper.

The other knobs matter as much. consolidateAfter defaults to 0s and the timer resets whenever a pod lands on or leaves the node. Disruption budgets default to nodes: 10% when none are set, accept reasons (Drifted, Underutilized, Empty, Unhealthy) and cron schedules in UTC, and the most restrictive budget wins. Pods can opt out with the karpenter.sh/do-not-disrupt annotation, either permanently or for a duration. Here is the NodePool shape I would start from on EKS:

# Karpenter v1.15 NodePool (karpenter.sh/v1 API), EKS provider
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        # Let Karpenter choose spot first, on-demand as fallback
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        # Allow Graviton; only works if every image is multi-arch
        - key: kubernetes.io/arch
          operator: In
          values: ["arm64", "amd64"]
      expireAfter: 720h            # recycle nodes every 30 days
  disruption:
    consolidationPolicy: Balanced  # added in v1.14.0
    consolidateAfter: 5m           # wait for pod churn to settle
    budgets:
      - nodes: "10%"               # never disrupt more than 10% at once
      - nodes: "0"                 # no voluntary consolidation in business hours
        reasons: ["Underutilized"]
        schedule: "0 8 * * mon-fri"  # cron in UTC
        duration: 10h
  limits:
    cpu: "2000"                    # hard ceiling on what this pool can buy

Consolidation is only as safe as your PodDisruptionBudgets and readiness probes. A workload with a single replica and no PDB will be moved, and if it takes two minutes to warm up, you will notice. Denser nodes also concentrate per-node load such as DNS lookups and conntrack entries, which is one reason I pair aggressive consolidation with NodeLocal DNSCache, covered in my CoreDNS troubleshooting guide.

Spot and Graviton: the two discounts that need engineering

Rightsizing and consolidation reduce how many node-hours you buy. Spot and Arm reduce the price of each one.

AWS advertises spot at up to 90 percent off on-demand, and the price is a two-minute interruption notice, delivered on a best-effort basis. Stateless services with several replicas, PDBs and quick startup are fine on spot. Karpenter deletes spot nodes during consolidation by default, but replacing a spot node with a cheaper spot node needs the SpotToSpotConsolidation feature flag and, for single-node replacement, at least 15 candidate instance types, because the cheapest pool is often the one most likely to be reclaimed. Broad instance flexibility is the real spot strategy. Cast AI's report notes that fewer than 2 percent of GPUs ran on spot for most of 2025, and that regional spot prices vary by two to five times, so GPU workloads are a different conversation.

On Arm, AWS says Graviton instances cost up to 20 percent less than comparable x86 instances and use up to 60 percent less energy for the same performance. Datadog found organisations using Arm put about 18 percent of EC2 compute spend on it, double the year before. The engineering cost is multi-arch images for every workload, including the third-party ones in your Helm charts, and a CI pipeline that builds and tests both. Once that exists, letting the node autoscaler choose architecture is a one-line requirement, as in the NodePool above.

Where GPU and AI workloads change the maths

GPUs break the playbook because the unit is expensive and indivisible. Cast AI measured 5 percent average GPU utilisation, which its CEO summarised in the press release as 95 percent of GPU capacity doing nothing. The levers are different: time-slicing and MIG to share a device, consolidating models onto fewer GPUs, and scheduling batch inference into spare capacity. OpenCost's new inference allocation helps with attribution, but the waste is mostly in reservation, not measurement. This is where platform discipline earns its keep in the AI era: the same habits of requests that match reality, attribution per team and capacity that scales down apply, with a much more expensive unit. If you run model servers on Kubernetes, the vLLM on Kubernetes guide covers the serving side.

FAQ

What is the fastest way to reduce Kubernetes costs?

Find and delete cluster idle first: consolidate nodes with Karpenter or the cluster autoscaler and remove abandoned namespaces. Then rightsize the largest requests, starting with the top ten workloads by requested CPU and memory, because cost is usually concentrated in a handful of services.

Is OpenCost free, and how is it different from Kubecost?

OpenCost is Apache-2.0 and a CNCF Incubating project, focused on cost allocation. IBM Kubecost 3.0 is built on OpenCost and adds multi-cluster views, budgets, and automated request and node sizing, with a free tier that includes automated request sizing up to 250 cores.

Does Karpenter save money compared with the Cluster Autoscaler?

It can, because it picks instance types per pending pod and actively replaces underused nodes, rather than scaling fixed node groups. The saving depends on letting it choose from many instance types and on workloads tolerating disruption through PDBs.

Is spot safe for production on Kubernetes?

For stateless, replicated services with PDBs and fast startup, yes, provided you spread across many instance types and handle the two-minute notice. Keep stateful systems, singletons and long-running jobs that cannot checkpoint on on-demand capacity.

This quarter I would do three things in order: deploy OpenCost and send each team its namespace cost every sprint, switch NodePools to the Balanced policy with business-hours budgets and a consolidateAfter of a few minutes, and pick the five largest workloads by requests for VPA recommendations applied in place. Spot and Graviton come after that, once images are multi-arch and PDBs exist, because a discount on capacity you do not need is still waste.

Related: FinOps for AI in 2026, Kubernetes as the Agent Control Plane in 2026 and GPU Clouds in 2026.

I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.

Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.


Related