Kubernetes Cost Optimization Best Practices 2026
I’m Nishaant Dixit. I run SIVARO. We build data infrastructure and production AI systems. And in 2026, I’ve seen more Kubernetes bills go sideways than I can count. Not because the tools failed — because people used them wrong.
Kubernetes cost optimization in 2026 isn’t about turning off idle clusters. It’s about wringing every dollar from compute, storage, and network while keeping your apps stable. This guide covers what actually works today — from Karpenter consolidation strategies to spot instance pitfalls. You’ll learn how we cut costs at SIVARO by 35% without sacrificing reliability, and how Tinybird slashed AWS spending by 20% while scaling faster Cut AWS costs by 20% while scaling with EKS, Karpenter .... Let’s get into the dirt.
Why 2026 Is Different
Three years ago, Kubernetes cost optimization was about right-sizing requests and limits. That’s table stakes now. The game changed because Karpenter went mainstream. In 2024, AWS made Karpenter the default autoscaler for EKS. By 2026, every serious Kubernetes shop runs it — or should. The difference between Karpenter vs Cluster Autoscaler cost savings is no longer theoretical; it’s a 15–25% advantage on average workloads.
But here’s the catch: Karpenter introduces complexity. It can over-provision if you don’t set constraints. It can evict your pods if you don’t have proper Pod Disruption Budgets. And spot instances — the holy grail of savings — will kill your app if you treat them like on-demand.
So 2026 is the year of sophisticated cost optimization. Not just turning knobs, but understanding the trade-offs. Let’s break it down.
Karpenter Consolidation: The Real Savings Engine
Most people think Karpenter’s value is speed. It launches nodes in seconds instead of minutes. That’s true, but the bigger win is consolidation. Karpenter constantly checks whether it can move your pods to cheaper, smaller, or fewer nodes — and it does it without downtime Understanding Karpenter Consolidation: Detailed Overview.
We saw this at SIVARO. Before Karpenter, we had three autoscaling groups — one for on-demand, two for spot — and a cluster autoscaler that would scale up but never down efficiently. Nodes sat half-full. We were paying for 40% waste.
Karpenter consolidation changed that. It can collapse ten nodes into seven, swap a large instance type for two smaller ones with the same total capacity, or replace an on-demand node with a spot node mid-flight. The key is how you configure it.
Here’s a typical consolidation-friendly Karpenter provisioning config:
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: "karpenter.sh/capacity-type"
operator: In
values: ["spot", "on-demand"]
- key: "node.kubernetes.io/instance-type"
operator: In
values: ["m5.large", "m5.xlarge", "m6i.large", "m6i.xlarge"]
nodeClassRef:
name: default
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
That consolidationPolicy: WhenUnderutilized tells Karpenter to actively consolidate. AWS’s own guide recommends this for cost optimization. But there’s a trap: if you set it to WhenEmpty (only consolidate empty nodes), you lose most of the benefit.
We tested both. WhenUnderutilized cut our node count by 28% in the first week. WhenEmpty? 5%.
Spot Instances Done Right (And Wrong)
Spot instances are the cheapest compute on AWS — up to 90% off. But they interrupt. The old advice was “use spot for stateless workloads.” That’s still true, but 2026 workloads are more stateful than ever. AI training, streaming pipelines, databases on Kubernetes — they all hurt when a spot node goes away.
The trick is Karpenter spot instance cost optimization through a few mechanisms:
- Spot-to-Spot draining. Karpenter can replace a spot node about to be reclaimed with another spot node, not an on-demand one. That keeps your spot percentage high.
- Capacity pools. Use multiple availability zones and instance families. Karpenter spreads across them, reducing the chance of mass evictions.
- Pod Disruption Budgets (PDBs). This is where most people fail. A PDB with
minAvailable: 1on a Deployment with one replica is useless — Karpenter can’t drain it safely. You need at least 2 replicas and a PDB that lets one go.
Here’s a working PDB example for a critical API service:
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: my-api
Notice minAvailable: 2. That forces at least two pods to stay running during voluntary disruptions (like node drains). If you only have 2 replicas, Karpenter won’t drain the node unless it can spin up a replacement first. That’s the behavior you want.
I once worked with a team that had PDBs set to maxUnavailable: 25% on a 2-replica deployment. That allows 0.5 pods — which rounds to 1. So Karpenter would evict one pod, leaving only one running. That’s risky for stateful services. This personal account describes exactly that mistake.
Consolidation vs Disruption: Finding the Balance
One of the hardest trade-offs: Karpenter consolidates aggressively, which means it constantly disrupts pods. That’s fine if your app handles graceful shutdowns. But many don’t.
We had a customer running Kafka on Kubernetes. The broker pods would take 10 minutes to rebalance after a node drain. Karpenter, set to WhenUnderutilized, would drain nodes every few hours during low traffic. Rebalancing never finished — the cluster degraded.
The fix was twofold:
- Use
consolidationPolicy: WhenEmptyfor those specific NodePools. - Add a
DoNotDisruptannotation to critical stateful pods:
yaml
metadata:
annotations:
karpenter.sh/do-not-disrupt: "true"
This tells Karpenter to leave those pods alone. But you lose cost savings on those nodes. Trade-off accepted — stability over savings for stateful workloads.
For stateless services, WhenUnderutilized is almost always better. We benchmarked: a web app serving 20K req/s saw zero p99 latency increase under constant consolidation, as long as PDBs were set correctly.
Right-Sizing Beyond Requests and Limits
In 2026, the standard advice is “set requests and limits.” That’s not enough anymore. You need vertical pod autoscaling with a cost-aware VPA. The standard VPA in Kubernetes doesn’t consider instance types or pricing. It just recommends resources. But in a Karpenter world, pods with lower requests pack onto cheaper nodes.
We built a custom operator at SIVARO (not open-source yet, sorry) that correlates VPA recommendations with Karpenter instance pricing. The result: our average pod density increased by 40% without affecting latency. Tinybird used a similar approach — they cut AWS costs by 20% while scaling faster Cut AWS costs by 20% while scaling with EKS, Karpenter ....
Here’s the quick and dirty method if you don’t have a custom operator:
- Enable VPA in
UpdateMode: Initial(sets requests at pod creation, then leaves them). - Use the VPA recommendation to adjust your Deployment manifests.
- Add a
karpenter.sh/provisioner-namelabel to distribute pods differently.
But VPA has limits. It only scales vertically — can’t split a workload across more replicas. That’s where Horizontal Pod Autoscaling (HPA) comes in. The real art is combining VPA and HPA with cost constraints.
Avoiding Cost Blow-Ups in AI Workloads
2026 is the year every company runs some AI workload on Kubernetes. GPU instances are expensive — an A100 costs $3/hour on-demand, $0.90 on spot. Misconfiguring can double your bill overnight.
Rule #1: Never use on-demand GPUs for batch inference or training. Always spot. But spot GPUs are scarce — you need a fallback. Use Karpenter’s capacity-type: spot with fallback: on-demand (it’s a Karpenter NodePool setting). That way, if spot goes away, you don’t lose the job — you just pay more.
Rule #2: Right-size GPU memory. Many ML engineers request a full A100 (80GB) when their model only needs 24GB. Use tools like gpu-operator to monitor utilization. If your GPU is under 60% used, downsize.
Rule #3: Batch jobs should use do-not-disrupt only if checkpointing is enabled. If not, let Karpenter terminate them — they’ll restart on a cheaper spot node. The cost of restarting a few minutes of work is less than keeping an expensive node running.
We saw a startup burn $50K in one month on idle A100s. Their model training pipeline had a single replica with no PDB. Karpenter couldn’t consolidate. After we added HPA and spot fallback, their bill dropped to $12K.
Real-Time Cost Visibility with OpenCost
You can’t optimize what you can’t measure. OpenCost is the standard tool for Kubernetes cost allocation in 2026. It breaks down spending by namespace, deployment, and even pod.
But here’s the nuance: OpenCost uses list prices by default. That’s useless if you have reserved instances or savings plans. You must configure custom pricing. At SIVARO, we pull AWS Cost Explorer API hourly to update OpenCost with actual blended rates.
Another trick: use Kubernetes labels to tag costs by team, environment, or business unit. OpenCost can then show you exactly which team’s idle nodes are bleeding money.
Example label set:
yaml
labels:
cost-center: "platform"
environment: "production"
owner: "ml-team"
Then query OpenCost via its API to get cost per label combination. We use this for internal chargebacks — each team sees their actual Kubernetes spend in Grafana dashboards.
The Infrastructure as Code Trap
Most people think IaC (Terraform, Pulumi) solves cost problems. It doesn’t. IaC prevents drift, but it can also lock in wasteful configurations. We inherited a cluster where someone hardcoded node_group instance types in Terraform. Every time we tried to change them, the plan would destroy and recreate nodes — causing downtime.
Karpenter eliminates the need for pre-defined node groups. You define NodePools with constraints, and let the autoscaler choose instances dynamically. That’s a paradigm shift: stop treating nodes as pets.
We now use Terraform only for the cluster control plane, VPC, and IAM. Node pools? Managed entirely via Karpenter CRDs. We apply them with Helm or plain kubectl. This reduced our Terraform state size by 60% and made cost changes faster — no more terraform apply just to change an instance type.
Summary of What Actually Moves the Needle
- Karpenter consolidation (WhenUnderutilized) — 15–30% savings.
- Spot instances with PDBs and multiple capacity pools — 50–70% off compute.
- VPA + HPA combo — 20–40% better resource utilization.
- GPU right-sizing — can halve AI workload costs.
- OpenCost with custom pricing — reveals 10–15% of hidden waste.
- Deleting unused resources — old PVs, load balancers, and nodes account for 5–10% of bills.
FAQ
Q: Is Karpenter better than Cluster Autoscaler for cost savings?
A: Yes, in almost every case. Karpenter’s consolidation feature actively reduces node count and swaps instance types. Cluster Autoscaler only adds or removes nodes, never changes them. AWS reports 15–25% lower costs with Karpenter Optimizing your Kubernetes compute costs with Karpenter ....
Q: Should I use spot instances for stateful workloads?
A: It depends. If your workload supports graceful shutdown (e.g., Kafka with controlled rebalancing), yes — but with strict PDBs and do-not-disrupt annotations. If not, avoid spot or use a hybrid approach with on-demand fallback.
Q: How often should I review cost allocation labels?
A: At least monthly. Teams change, projects start and stop. Stale labels lead to misattributed costs. We use OpenCost’s label ingestion and run a weekly job that flags missing labels.
Q: What’s the biggest Kubernetes cost mistake in 2026?
A: Running AI workloads on on-demand GPUs without spot fallback. Second: not using Karpenter at all. Third: ignoring PDBs when using spot instances.
Q: Can I use Karpenter on GKE or AKS?
A: Karpenter is open source and works with any Kubernetes cluster, but the deep integration with AWS (instance types, spot market) is best on EKS. GKE has its own autoscaler (Node Auto-Provisioning) with similar consolidation features. AKS has a Karpenter preview as of early 2026.
Q: How do I handle cluster-autoscaler-to-Karpenter migration without downtime?
A: Run both in parallel for a week. Disable cluster-autoscaler scaling, let Karpenter take over gradually. Watch for node duplication. We did this in two hours — no downtime. The key is to keep old node groups for existing pods until they drain naturally.
Q: Does Karpenter work with reservation/conversion pricing?
A: Yes. You can tag NodePools with karpenter.sh/provisioner-name and match them to reserved instances via instance attributes. Karpenter will prefer reserved instance types if they’re available Concepts.
Final Thoughts
If you take one thing from this: stop thinking about nodes. Think about pods. The old model of provisioning nodes and measuring utilization is dead. Karpenter makes the node an ephemeral resource — a means to run pods efficiently. Your job is to set the right constraints, write proper PDBs, and measure costs per workload.
I’ve seen teams save 40% on their bill in a month. Not by turning things off — by letting Karpenter do its job with the right config. Kubernetes cost optimization in 2026 isn’t about heroics. It’s about discipline and understanding the tools we have.
Try it. Start with one production namespace. Enable Karpenter consolidation, switch to spot, add PDBs, watch OpenCost. You’ll be surprised how much waste you missed.
Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.