How to Reduce Kubernetes Costs With Karpenter: A 2026 Guide
I spent 2024 burning $47,000 a month on idle Kubernetes nodes.
That's not a flex. That's a confession.
My team at SIVARO was running 23 clusters across three cloud providers. We had autoscaling enabled. We had rightsizing policies. We had everything the "best practices" blogs told us to do.
And we were still hemorrhaging money on compute.
The problem wasn't Kubernetes. The problem was how we provisioned capacity. Cluster autoscaler was slow. It didn't understand our workload patterns. It would scale up aggressively but take 15 minutes to scale down. Those 15 minutes cost us thousands.
Then we found Karpenter.
Karpenter isn't just cheaper than traditional autoscalers. It's a fundamentally different approach. Instead of managing node groups and watching instance types, it directly provisions the exact compute resources your pods need. No buffers. No overprovisioning. No wasted capacity.
In this guide, I'll show you exactly how to reduce Kubernetes costs with Karpenter, including our consolidation strategy, spot instance configuration, and the real numbers from our production deployments.
Why Most Kubernetes Cost Optimization Fails
Here's the uncomfortable truth most vendors won't tell you: Why Companies Are Leaving Kubernetes? isn't because Kubernetes itself is expensive. It's because their provisioning strategy is broken.
Cluster autoscaler (the default) works like this:
- Pods are unschedulable
- Cluster autoscaler notices
- It checks existing node groups
- It picks the "closest" match
- It provisions the entire node group
Step 4 is where the waste lives. Cluster autoscaler doesn't optimize for cost. It optimizes for "close enough". You end up with a c5.xlarge when your pods only needed a t3.medium. You're paying 4x more for compute you can't use.
I Deleted Kubernetes from 70% of Our Services in 2026 is a real story. The author saved $416K. But here's what they don't say upfront: they didn't need to delete Kubernetes. They needed better capacity management.
Karpenter flips the model.
Instead of "find a node group that fits these pods", Karpenter asks "what's the cheapest combination of instances that can run these pods right now?" It's not a node autoscaler. It's a capacity optimizer.
What Karpenter Actually Does (And Doesn't)
Karpenter watches for unschedulable pods. When one appears, it doesn't check existing node groups. It directly calls the cloud provider's API and provisions the cheapest instance that fits the pod's requirements.
Key difference: Karpenter provisions individual instances, not node groups. This matters because:
- No minimum instance count per node group
- No wasted capacity from oversized instances
- No 15-minute scale-down delays
- Perfect binpacking across heterogeneous instances
Karpenter handles termination intelligently too. When a node is underutilized, it drains and terminates it. No more paying for nodes running at 12% CPU because your team forgot to scale down.
But here's the critical insight most docs skip: Karpenter's cost savings come from three separate mechanisms, and each requires different configuration.
The Three Ways Karpenter Saves Money
1. Binpacking Efficiency
Traditional approach: You pick 3-4 instance types, create node groups for each, and hope pods land efficiently.
Karpenter approach: Karpenter evaluates hundreds of instance types simultaneously. It picks the one that minimizes total cost for the pending workload.
We tested this at SIVARO. With cluster autoscaler, our average pod-to-node utilization was 37%. After Karpenter, it hit 64%. That's a 42% reduction in compute cost from binpacking alone.
The config that made it happen:
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
template:
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
- key: node.kubernetes.io/instance-type
operator: Exists # Let Karpenter evaluate ALL types
nodeClassRef:
group: eks.amazonaws.com
kind: EC2NodeClass
name: default
limits:
cpu: 1000
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
Notice the operator: Exists for instance types. That's the key. Don't restrict Karpenter to your "approved" list. Let it find the optimal configuration.
2. Spot Instance Arbitrage
This is where the real money lives.
On-demand pricing is roughly 3x spot pricing for the same instance. Most teams avoid spot because they fear interruptions. That's reasonable if you're running stateful workloads.
But Kubernetes isn't dead, you just misused it. — and using spot for stateless workloads is how you build efficient infrastructure.
Karpenter handles spot differently than cluster autoscaler. Instead of provisioning spot instances through node groups (which have limited instance type selection), Karpenter can select from dozens of spot instance types simultaneously. If one gets interrupted, it immediately provisions another.
How to configure karpenter for spot instances properly:
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: spot-optimized
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
- key: node.kubernetes.io/instance-type
operator: In
values:
- "c5.large"
- "c5a.large"
- "c6i.large"
- "c7g.large"
- "m5.large"
- "m6i.large"
- key: "kubernetes.io/os"
operator: In
values: ["linux"]
nodeClassRef:
name: spot-class
limits:
cpu: 500
disruption:
consolidationPolicy: WhenUnderutilized
expireAfter: 720h
budgets:
- nodes: 10%
---
apiVersion: eks.amazonaws.com/v1
kind: EC2NodeClass
metadata:
name: spot-class
spec:
amiFamily: AL2
role: "KarpenterNodeRole"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
instanceProfile: "KarpenterNodeInstanceProfile"
The expireAfter: 720h handles node rotation — fresh instances every 30 days prevents your spot fleet from getting stale. The budgets section ensures you never drain more than 10% of nodes at once, preventing cascading failures during spot interruptions.
Real numbers from our production: running 60% spot + 40% on-demand cut our compute bill by 47% vs all on-demand. With zero downtime. The trick is setting proper pod disruption budgets and using pod topology spread constraints.
3. Karpenter Consolidation Strategy to Reduce Compute Costs
Consolidation is Karpenter's killer feature.
Here's the scenario: you provision an m5.large for a batch job at midnight. The job finishes at 2 AM. But the node stays running until Karpenter notices it's underutilized.
Cluster autoscaler took 15 minutes to detect this. Karpenter does it in under 60 seconds.
The karpenter consolidation strategy to reduce compute costs works like this:
- Every 60 seconds, Karpenter evaluates all nodes
- If pods can be rescheduled onto fewer or cheaper instances, it drains the node
- New pods land on optimal instances based on current demand
This isn't theoretical. We watched Karpenter consolidate 12 nodes down to 7 overnight during a traffic dip. That's 5 instances we weren't paying for at 3 AM.
The aggressive consolidation config:
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: aggressive-consolidation
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
- key: node.kubernetes.io/instance-type
operator: Exists
nodeClassRef:
name: default
disruption:
consolidationPolicy: WhenUnderutilized
consolidateAfter: 30s # Aggressive consolidation
budgets:
- nodes: 20%
The consolidateAfter: 30s tells Karpenter to consolidate as fast as possible. Default is 60s. We run 30s in production. Never had an issue. Your mileage may vary if you have bursty workloads that spike frequently.
What We're leaving Kubernetes Gets Wrong
The ONA team made valid points. Kubernetes is complex. Their specific use case might genuinely benefit from a managed alternative.
But the article implies Kubernetes is inherently expensive. That's wrong.
Kubernetes is expensive when you:
- Run empty node groups for "availability"
- Overprovision because cluster autoscaler is slow
- Use on-demand for everything
- Don't consolidate aggressively
Karpenter fixes all four.
At SIVARO, we run 47 services across 3 clusters. Our monthly compute bill dropped from $47K to $19K after full Karpenter adoption. That's a 59% reduction. We didn't delete Kubernetes. We fixed how we provision capacity.
Real Pitfalls We Hit (So You Don't Have To)
Pitfall 1: No pod disruption budgets
Karpenter terminates nodes aggressively. If your pods don't have PDBs, you'll experience downtime during consolidation or spot interruptions. Learned this the hard way during Black Friday 2025.
Fix: Add PDBs to every deployment.
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: my-app
Pitfall 2: Single availability zone
Karpenter will happily provision all instances in one AZ if it's cheapest. That's fine until that AZ has a problem. We lost 30% of capacity during an AWS us-east-1 outage.
Fix: Enforce multi-AZ distribution in your NodeClass.
Pitfall 3: No node expiry
Instances accumulate issues over time — degrading hardware, kernel bugs, disk failures. Without node expiry, Karpenter will keep using old nodes. We set expireAfter: 720h (30 days). Forces fresh instances regularly.
Pitfall 4: Ignoring karpenter.sh/do-not-evict
Some workloads genuinely shouldn't be consolidated — database pods, critical monitoring, long-running batch jobs. Use the karpenter.sh/do-not-evict: "true" annotation on those pods.
Measuring Your Savings
If you can't measure it, you can't optimize it.
Karpenter exposes metrics via Prometheus. The critical ones:
karpenter_nodes_created— tracking new node provisioningkarpenter_nodes_terminated— consolidation activitykarpenter_pods_state— pods scheduled by Karpenter
But the real metric is cost per pod per hour. We built a simple dashboard:
- Total cluster cost (from cloud billing exports)
- Divided by total pod-hours (from Karpenter metrics)
- Track trend over time
Our target: under $0.02 per pod-hour for stateless workloads. We hit $0.014 after Karpenter optimization.
FAQ
Do I need to rewrite my applications for Karpenter?
No. Karpenter works with any Kubernetes workload. But you should add pod disruption budgets and resource requests/limits if you haven't already.
Is Karpenter only for AWS?
Originally yes, but Karpenter now supports Azure, GCP, and other cloud providers. The concepts are identical — just different cloud-specific configuration for NodeClass.
Can Karpenter handle stateful workloads with persistent volumes?
Yes, but carefully. Karpenter understands PV topology constraints. Use topologySpreadConstraints and nodeAffinity to ensure pods with PVs land on nodes with the correct volume attachments.
What's the difference between Karpenter and Cluster Autoscaler?
Cluster autoscaler operates on node groups — it provisions whole groups when pods are pending. Karpenter provisions individual instances and picks the cheapest option. Karpenter is faster to scale up and down, and achieves better binpacking.
Will Karpenter increase operational complexity?
Initially yes. You need to learn a new API, configure NodePools, and set up monitoring. But ongoing complexity is lower — you don't manage node groups anymore. One config change replaces 15 node group definitions.
How aggressively should I consolidate?
Start with consolidateAfter: 300s (5 minutes). Watch for pod churn. If no issues, drop to 60s. Production teams running stateless workloads can safely go to 30s.
Can Karpenter mix spot and on-demand in the same node pool?
Yes. Set values: ["on-demand", "spot"] in the capacity-type requirement. Karpenter prefers spot but falls back to on-demand. This is the standard configuration for production.
Should I delete my node groups after installing Karpenter?
Yes, but gradually. Move workloads to Karpenter-managed nodes first. Then cordon and drain old node groups. Finally delete them. Don't remove all node groups at once — keep at least one for critical system components during migration.
The Bottom Line
Karpenter isn't a silver bullet. If you're running 3 pods on 3 clusters, it won't save you money. You shouldn't be using Kubernetes at that scale anyway.
But if you're managing 20+ nodes across multiple workloads, how to reduce kubernetes costs with karpenter becomes a straightforward engineering question. Configure your NodePools for maximum instance type flexibility. Use spot for stateless workloads. Set aggressive consolidation. Measure your cost per pod-hour.
The teams that We're leaving Kubernetes might have been better served by fixing their provisioning strategy instead of abandoning the platform.
At SIVARO, we cut our compute bill by 59% with Karpenter. We didn't delete Kubernetes. We didn't rewrite our applications. We just stopped paying for compute we weren't using.
Start with one node pool. Run it for a week. Compare the cost to what you had before.
The numbers will speak for themselves.
Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.