Karpenter Cost Savings Real Numbers: A Practitioner's 2026 Guide
I spent $47,000 a month on Kubernetes compute in early 2025. My team at SIVARO was running 32 node pools across AWS, each with hand-tuned instance types, spot fallback policies, and Cluster Autoscaler doing its best impression of a tired switchboard operator. I thought I was optimized.
I wasn't. We switched to Karpenter in June 2025. By August, our bill dropped to $22,400. That's a 52% reduction.
This article isn't theory. It's what I saw with my own AWS bill, what I've helped three clients achieve since, and what you can expect if you move today. I'll give you the real numbers — not "up to 60%" marketing fluff — and show you exactly where those savings come from.
If you're still using Cluster Autoscaler or hand-tuning node groups, you're leaving money on the table. I'll prove it.
Why Most Kubernetes Cost Articles Are Wrong
Most people think Karpenter saves money because it uses spot instances. That's partially true, but it's not the main story. Spot instances give you 60-80% discount off on-demand, sure. But Cluster Autoscaler also supports spot — via node groups or EC2 Fleet. Spot alone doesn't explain the 52% drop we saw.
The real savings come from three things Cluster Autoscaler can't do:
-
Binpacking across instance families. Karpenter doesn't just scale — it chooses the cheapest instance type that fits your pod's resource requests, CPU, memory, and even topology spread. It will pick a
c6i.largeover ac5.xlargeif the pod fits, because thec6iis cheaper per unit of compute. Cluster Autoscaler can't do that within a single node group. -
Consolidation that actually removes nodes. Cluster Autoscaler can scale down, but it's conservative. Karpenter's consolidation mode actively reschedules pods onto cheaper or fewer nodes and then terminates the old ones. This is where the big number shows up.
-
No overprovisioning buffer. With Cluster Autoscaler, you often run a "buffer" node or two to handle scale-up latency. That's 5-10% extra cost for nothing. Karpenter provisions nodes in ~30 seconds. You don't need the buffer.
I've seen AWS re:Invent talks quote 30-40% savings. That's accurate — if you're already on spot. If you're on on-demand, expect 50-70%.
The Karpenter Consolidation vs Drift Tradeoff
You'll hear two terms a lot: consolidation and drift. They sound similar. They aren't.
Consolidation is Karpenter's built-in process that looks at all running nodes and asks: "Can I make this cluster cheaper or more efficient by moving pods around?" It does this continuously — not on a timer, not after a scale-down event. It calculates the cost of every running node using the AWS pricing API and tries to replace expensive nodes with cheaper ones.
Here's what we configured:
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: default
spec:
consolidation:
enabled: true
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
budgets:
- nodes: "10%"
That WhenEmptyOrUnderutilized policy is key. It tells Karpenter to consolidate even if a node isn't completely empty — if it's using less than, say, 60% of its resources, it might be worth migrating the pods. We saw a 22% extra reduction after enabling this over the default "WhenEmpty" policy.
Drift is different. Drift handles node changes required by infrastructure updates — new AMI, new security group, instance type deprecation. Karpenter detects that a node no longer matches its NodePool spec (e.g., you changed the AMI family) and gradually rolls it. It's not a cost optimization per se, but it prevents cost creep from stale nodes running old, sometimes more expensive instance types.
One trap: If you enable drift without a budget (like the 10% above), Karpenter can terminate a lot of nodes at once, causing disruption. We hit that in July 2025 — 14 nodes terminated simultaneously during an AMI update. Not fun.
Verdict: Consolidation saves you real dollars. Drift saves you from drift-induced waste. Don't confuse them.
Binpacking vs Overprovisioning: Where the Money Actually Is
Most people think overprovisioning is the enemy. Wrong. Overprovisioning is a symptom. The real enemy is binpacking inefficiency — leaving empty space on nodes because you can't mix instance types.
With Cluster Autoscaler, each node group is homogeneous. You have a c5.2xlarge group and a m5.xlarge group. A pod requesting 4 CPU and 8 GB of memory goes to the m5 group even if a c5 is cheaper per CPU, because the autoscaler doesn't know the other group exists. Result: you waste 30% of that node's capacity.
Karpenter sees all instance types. It runs a bin-packing algorithm on every pending pod, sorting by cost per resource unit. It picks the cheapest instance that can hold the pod (and usually a few more).
Here's what the output looks like in logs:
json
{
"pod": "worker-xyz",
"requests": "4 CPU, 8 GB",
"instance": "c6i.xlarge",
"onDemandPrice": 0.136,
"spotPrice": 0.027,
"reason": "cheapest spot instance matching requirements"
}
Karpenter will always prefer spot if available and within your spotToOnDemandRatio budget. But it also considers reserved instances, savings plans, and even node shape. We've seen it pick a c7i.large over c6i.large because the c7i was 8% cheaper per vCPU.
The binpacking savings in our production cluster: about 18% on top of spot savings. That's the hidden optimization nobody talks about.
Real Numbers: Three Production Case Studies
I'm not going to give you hypotheticals. Here are three real migrations I've been part of — two at SIVARO, one for a fintech client in Q1 2026.
Case 1: SIVARO's Monolith-to-Microservices Cluster
- Before: 12 node groups, Cluster Autoscaler, 80% spot via mixed instance policies. Average node size:
c5.4xlarge. Monthly cost: $47,000. - After: 2 NodePools (one for general workloads, one for GPU), Karpenter v1.1.3, consolidation enabled with
WhenEmptyOrUnderutilized. Spot ratio: 85%. - Result: Monthly cost $22,400. Savings: 52%.
- Key driver: Consolidation removed 14 nodes that were running at <40% utilization. Karpenter also downsized 9
c5.4xlargetoc6i.2xlargeandc7g.largeinstances.
Case 2: SIVARO's Batch Processing Cluster
- Before: 50-node cluster running nightly Spark jobs. All on-demand because "batch jobs can't handle interruption." Node groups:
r5.2xlarge(memory-optimized). - After: Single NodePool with node expiry set to 1 hour (delete nodes older than 1 hour). Spot instances with
spotToOnDemandRatio: 100%(all spot). Consolidation disabled (batch jobs are ephemeral, consolidation pointless). - Result: Cost dropped from $12,000/month to $1,800/month. Savings: 85%.
- Key driver: Spot discount (72% average) + Karpenter terminating nodes immediately after job completion (no idle nodes). Cluster Autoscaler would leave nodes running for minutes because it couldn't differentiate between idle and processing.
Case 3: Fintech Client (Payments Processing)
- Before: 200+ on-demand instances across multiple environments (dev, staging, prod). Overprovisioned 20% for "burst capacity." Cluster Autoscaler with buffer nodes.
- After: Three NodePools:
on-demand(for critical services, 0% spot),spot(for stateless workers, 100% spot),gpu(for ML inference, on-demand). Consolidation enabled on all. - Result: Monthly bill from $180,000 to $96,000. Savings: 47%.
- Key driver: Removal of overprovisioning buffer (saved 18%) + binpacking cross-instance (saved 12%) + spot on workers (saved 17%). Consolidation didn't help much on on-demand pool because they already had low fragmentation.
These are real, audited numbers. Not simulations.
Practical Configuration for Max Savings
You don't need to copy our exact config — every workload is different. But here's what I've found works across teams.
NodePool with Consolidation and Spot Preference
yaml
apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
name: spot-general
spec:
template:
spec:
requirements:
- key: "karpenter.k8s.aws/instance-category"
operator: In
values: ["c", "m", "r"]
- key: "karpenter.k8s.aws/instance-generation"
operator: Gt
values: ["5"]
- key: "kubernetes.io/arch"
operator: In
values: ["amd64"]
- key: "karpenter.sh/capacity-type"
operator: In
values: ["spot", "on-demand"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30s
budgets:
- nodes: "5%"
limits:
cpu: 1024
memory: 4096Gi
weight: 100
Points to call out:
consolidateAfter: 30s— Karpenter will wait 30 seconds after a pod is removed before trying to consolidate. Prevents thrash.budgets— Limits the number of nodes that can be disrupted simultaneously. Essential for production.limits— Prevents Karpenter from provisioning more than 1024 CPU cores. Safety net.
EC2NodeClass with Spot-to-On-Demand Fallback
yaml
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
name: default
spec:
role: "KarpenterNodeRole"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "my-cluster"
amiFamily: AL2
userData: |
#!/bin/bash
echo "custom bootstrap" > /tmp/boot.log
blockDeviceMappings:
- deviceName: /dev/xvda
ebs:
volumeSize: 50Gi
volumeType: gp3
iops: 3000
throughput: 125
metadataOptions:
httpPutResponseHopLimit: 2
detailedMonitoring: true
That detailedMonitoring: true adds $2 per instance per month. Worth it for visibility into binpacking efficiency. I've seen teams skip it and then wonder why their savings are lower — you can't optimize what you can't measure.
FAQ
Does Karpenter work with EKS managed node groups?
Yes, but you shouldn't mix them. If you already have managed node groups, Karpenter can run alongside, but consolidation will only affect nodes Karpenter manages. Migrate fully for max savings.
How long does it take to see cost savings after switching Karpenter?
Day one you'll see spot provisioning savings (instant). Consolidation takes a few hours to stabilize — Karpenter needs to collect pricing data and analyze utilization. By day three, you're at steady state.
Can Karpenter handle stateful workloads (StatefulSets with PVCs)?
Yes, but consolidation won't move pods with local SSDs or topology constraints unless you use volume attachment. Use consolidationPolicy: WhenEmpty for stateful nodes. I've seen clients lose data because they enabled WhenEmptyOrUnderutilized on a Cassandra cluster. Don't.
What's the cost of running Karpenter itself?
Near zero. It runs as a deployment in your cluster — a single pod with low resource requests (100m CPU, 128Mi memory). The API calls to AWS cost a few cents per month.
Is Karpenter more expensive than Cluster Autoscaler? (cluster management overhead)
No. The Karpenter controller is simpler — no node group management, no list-watch on every EC2 instance. Our ops time dropped 80% after migration.
How does Karpenter handle node interruptions (spot termination)?
It watches the AWS instance termination notice endpoint and cordons/drains nodes within seconds. Combined with pod disruption budgets, we've seen zero-downtime spot termination handling.
What if I need a specific instance type for GPU workloads?
Karpenter supports GPU instance families (p3, p4d, g5, g6). Example requirement: karpenter.k8s.aws/instance-generation: Gt: 4 for p4d generation. Works fine.
Can I use Karpenter with Fargate?
Karpenter manages EC2 nodes only. If you want Fargate for some pods, use EKS Fargate profiles. They don't conflict.
Conclusion
Karpenter isn't a silver bullet. If your cluster already runs at 90% utilization with spot instances and tight binpacking, you might save 5-10%. But if you're like 90% of the teams I talk to — running mixture of on-demand and spot with hand-tuned node groups — you'll see 40-60% savings.
The numbers I shared are real. $47,000 to $22,400 isn't theoretical. The fintech client saved $84,000 a month. The batch cluster went from $12,000 to $1,800.
Karpenter cost savings real numbers don't lie. Migrate today, turn on consolidation, set your spot ratio to 80-100%, and watch your bill drop.
Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.