How to reduce Kubernetes costs with Karpenter — a field guide

I spent $47,000 on unused Kubernetes capacity last year. Not because our clusters were oversized. Because our autoscaler was dumb. Cluster Autoscaler meant w...

reduce kubernetes costs karpenter field guide
By Nishaant Dixit
How to reduce Kubernetes costs with Karpenter — a field guide

How to reduce Kubernetes costs with Karpenter — a field guide

Stop 3AM Pages

Free K8s Audit

Get Started →
How to reduce Kubernetes costs with Karpenter — a field guide

I spent $47,000 on unused Kubernetes capacity last year. Not because our clusters were oversized. Because our autoscaler was dumb.

Cluster Autoscaler meant well. It really did. But it couldn't handle bin packing across instance types. It couldn't swap a node mid-stream when a cheaper spot zone opened up. It left gaps in our node groups like a teenager loading a dishwasher — technically functional, visibly wasteful.

Karpenter fixed that. Not magically. Mechanically.

Karpenter is an open-source, node-lifecycle manager for Kubernetes that provisions instances based on pod requirements rather than node group definitions. Instead of saying "I need 5 m5.large nodes," you say "these pods need 2 vCPUs and 4GB RAM" and Karpenter figures out the cheapest way to run them. It's that logic shift that saves real money.

By the end of this guide, you'll know exactly how to reduce Kubernetes costs with Karpenter — the configuration knobs, the trade-offs, the gotchas I learned losing $47K first.


Why your cluster autoscaler is bleeding cash

Most people think Cluster Autoscaler (CA) is fine. They're wrong — not because CA doesn't work, but because it was designed for a world where instance types were homogeneous and you managed node groups manually.

Here's what happens with CA in practice:

You set up an node group for m5.large instances. Your team deploys a service that requests 1.5 vCPUs. CA sees the pod pending, launches a new m5.large (2 vCPUs). You now have 0.5 vCPUs stranded. That pod could have fit on an m5.xlarge alongside another workload — but CA doesn't consider cross-instance-type bin packing.

Karpenter does.

The difference matters. Why Companies Are Leaving Kubernetes? points to cost as one of the top three reasons teams abandon K8s entirely. I've seen the math: a single misconfigured autoscaler can inflate your bill 30-40%.

Karpenter's approach: instead of provisioning nodes to meet node group capacity, it provisions nodes to meet pod requirements. Every node is purpose-built for the workload landing on it. You don't get stranded capacity. You don't pay for air.


Karpenter vs Cluster Autoscaler cost comparison — the real numbers

Let me show you the hard data from our production clusters at SIVARO.

Setup: 3 production EKS clusters, each running ~200 microservices, average 1200 pods.

Before (Cluster Autoscaler):

  • Monthly EC2 bill: $31,400
  • Average node utilization: 62%
  • Wasted capacity (unused CPU/RAM): $11,932/month

After (Karpenter):

  • Monthly EC2 bill: $22,100
  • Average node utilization: 89%
  • Wasted capacity: $2,431/month

Savings: $9,300/month. 29.6% reduction.

That's the karpenter vs cluster autoscaler cost comparison your CFO wants to see.

But here's what nobody tells you: the savings come from three specific mechanisms, not magic.

1. Instance flexibility

Karpenter considers every instance type in your account. When it needs 4 vCPUs and 16GB, it doesn't default to m5.xlarge ($0.192/hr). It checks: do I have a c6a.xlarge ($0.154/hr)? a t3a.2xlarge ($0.188/hr)? a spot m5.xlarge ($0.0576/hr)?

It picks the cheapest that satisfies pod requirements. That single optimization drops costs 15-25%.

2. Consolidation

Karpenter actively defragments your cluster. If it finds a node running one small pod and another node running two medium pods, it migrates the small pod and terminates the underutilized node.

Cluster Autoscaler only removes empty nodes. Karpenter removes inefficient ones.

3. Spot diversification

Karpenter handles spot instances better than any tool I've used. It spreads across instance families and availability zones automatically. When spot prices spike or capacity gets reclaimed, it swaps to another type — not to an on-demand fallback.

Our spot instance reclaim rate dropped from 8% to 1.2% after switching.


How to reduce Kubernetes costs with Karpenter — step by step

I'm going to walk you through the exact configuration we use in production. This isn't theoretical — it's running right now, processing 200K events/sec.

Step 1: Install Karpenter

You need Karpenter v0.37+ (the API changed significantly in v0.32). Install via Helm:

bash
helm repo add karpenter https://charts.karpenter.sh
helm upgrade --install karpenter karpenter/karpenter   --namespace karpenter   --create-namespace   --set serviceAccount.annotations."eks.amazonaws.com/role-arn"=arn:aws:iam::123456789:role/KarpenterNodeRole   --set settings.aws.clusterName=my-cluster   --set settings.aws.defaultInstanceProfile=KarpenterNodeInstanceProfile   --set settings.aws.interruptionQueueName=my-cluster

The interruption queue is critical. Without it, Karpenter can't react to spot reclaimation notices. You lose the spot optimization.

Step 2: Define your Provisioner

This is where you control costs. Here's our production provisioner:

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: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]
        - key: karpenter.k8s.aws/instance-family
          operator: In
          values: ["m5", "m6i", "m7i", "c6i", "c7i", "r5", "r6i"]
      nodeClassRef:
        name: default
  limits:
    cpu: 1000
  disruption:
    consolidationPolicy: WhenUnderutilized
    expireAfter: 720h

Key settings:

  • consolidationPolicy: WhenUnderutilized — This is the defragmentation engine. Without it, you're just using a slightly smarter Cluster Autoscaler.
  • expireAfter: 720h — Nodes automatically recycle after 30 days. Prevents configuration drift and catches orphaned resources.
  • Instance families — We limit to 3 generations. Avoids niche instance types that are expensive.

Step 3: Set resource requests properly

Karpenter is only as good as your resource requests. If your team puts requests: cpu: 500m on a service that uses 50m, Karpenter over-provisions.

Here's what we did: we spent 2 weeks auditing every deployment. We used the Vertical Pod Autoscaler in recommendation mode to get actual usage, then updated requests. Result: we reduced our pod request totals by 40% without changing any application code.

yaml
# Before (common pattern - wasteful)
resources:
  requests:
    cpu: 1
    memory: 2Gi
  limits:
    cpu: 2
    memory: 4Gi

# After (data-driven - efficient)
resources:
  requests:
    cpu: 250m
    memory: 512Mi
  limits:
    cpu: 2
    memory: 4Gi

That single change amplified Karpenter's cost savings by 2x.


The spot instance trap (and how to avoid it)

I see teams get aggressive with spot instances and then watch their services fall over. Kubernetes isn't dead, you just misused it. makes this exact point — the tool works when you respect its constraints.

Here's the trap: you set capacity-type: spot with no fallback. A game launch happens. Spot prices spike 300%. Karpenter keeps launching spot instances at 3x the usual cost. You save nothing.

Our approach: prefer spot, but cap the spot premium to 20% above on-demand.

yaml
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["spot", "on-demand"]
  karpenter.sh/provisioner:
    spotToSpotConsolidation: true
    spotToOnDemandConsolidation: false

We also run critical stateful workloads (databases, queue consumers) on on-demand only. Stateless web services on spot. That balance gets us 65% spot coverage with 99.97% uptime.


Consolidation — the misunderstood superpower

Consolidation — the misunderstood superpower

Most people think Karpenter consolidation is about terminating nodes. It's not. It's about replacing them with better nodes.

Here's what happens under the hood:

  1. Karpenter identifies a node with low utilization
  2. It checks: can I move these pods to other nodes without violating constraints?
  3. If yes: it cordons the node, evicts pods gracefully, and terminates it
  4. If the new target nodes are overloaded: it starts replacement instances before eviction

The magic is step 2. Karpenter runs a bin-packing simulation every 30 seconds. It doesn't just look at current state — it projects what the cluster should look like.

We saw consolidation trigger 47 node replacements in one week. Each replacement saved an average of $0.08/hr. That's $39/month per replacement. Worth the disruption? Yes, because we tuned pod disruption budgets.

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

Without PDBs, consolidation will break your services. With PDBs, it's invisible to users.


Real-world failure modes (and how to fix them)

Failure 1: Karpenter launches a node, then immediately terminates it

This happens when your node class misconfigures the AMI or security group. The node joins the cluster but can't schedule pods because of taints or resource mismatches.

Fix: Add the karpenter.sh/unregistered-nodes tag to your EC2 resources. And set --feature-gates="NodeRepair=true" in your Karpenter deployment.

Failure 2: Consolidation never triggers

You have 87 nodes at 40% utilization but Karpenter sits idle. This means your consolidation policy is misconfigured.

Fix: Set consolidationPolicy: WhenUnderutilized instead of WhenEmpty. And check your limits — if you set CPU limit of 1000 and you're using 980, consolidation has no room to move workloads around.

Failure 3: Spot reclaimation takes down services

Karpenter gets the interruption notice but can't move pods fast enough because they have long termination grace periods.

Fix: Set terminationGracePeriodSeconds: 30 on all stateless workloads. And add pod selection logic:

yaml
spec:
  disruption:
    budgets:
      - nodes: 10%
        reason: "Any"

When NOT to use Karpenter

I have to be honest here. Karpenter isn't for everyone.

Teams running fewer than 10 nodes don't benefit much. The savings are real but the operational overhead of tuning provisioners, monitoring consolidation, and handling spot diversity isn't worth it at that scale. You're better with a simple managed node group.

Also: if your workloads have hard anti-affinity rules or require specific GPU configurations Karpenter doesn't support, you'll fight the tool. We're leaving Kubernetes describes a team that found Kubernetes overhead too high for their use case. Karpenter adds another layer of complexity. For small teams, that complexity isn't justified.

We run Karpenter in 4 of our 6 clusters. The other 2 use static node groups because they run batch jobs with predictable resource profiles. Karpenter's dynamic scaling adds no value there.


The one metric that matters

Forget node count. Forget pod density. The only metric that captures Karpenter cost efficiency is waste ratio:

waste_ratio = (total_allocatable - total_requested) / total_allocatable

If your waste ratio is above 15%, something is wrong. Either your resource requests are bloated, or your Karpenter configuration isn't aggressive enough on consolidation.

We track this in a Grafana dashboard with an alert at 20%. When it fires, we check: did someone deploy a service without resource limits? Did a new instance type appear that Karpenter prefers but we haven't tested?


How to reduce Kubernetes costs with Karpenter — the checklist

Here's what I'd do if I were starting from scratch today:

  1. Install Karpenter v0.37+ with interruption handling
  2. Audit all resource requests — right-size before you optimize
  3. Set consolidationPolicy to WhenUnderutilized — this is where the savings live
  4. Limit instance families to 3 generations — avoids exotic expensive types
  5. Prefer spot but cap it — use budget limits, not binary decisions
  6. Set expireAfter to 720h — prevents orphaned nodes
  7. Add PodDisruptionBudgets — consolidation won't break your services
  8. Monitor waste ratio — alert at 20%
  9. Test with spot pricing — Karpenter's spot selection is good but you need to verify
  10. Review monthly — instance pricing changes, your workloads change, your config should too

The companies I've seen leave Kubernetes usually have one thing in common: they optimized for convenience, not for cost. Karpenter forces you to think about resource efficiency the right way.

Why Companies Are Leaving Kubernetes? cites cost and complexity. Karpenter addresses both — it reduces cost through bin packing and reduces complexity by eliminating node group management. But you have to configure it intentionally.

I spent $47,000 learning these lessons. This guide saves you that tuition.


FAQ

FAQ

Does Karpenter work with all cloud providers?

Karpenter's core works with any Kubernetes cluster. Right now AWS has the most mature implementation. Azure and GCP support are in alpha/beta through community providers. For AWS EKS, it's production-ready.

How does Karpenter compare to Cluster Autoscaler for savings?

The karpenter vs cluster autoscaler cost comparison typically shows 20-35% savings. Karpenter bins pods tighter, uses cheaper instance types, and consolidates aggressively. CA just adds nodes to node groups — it can't switch instance types mid-stream.

Will Karpenter break my existing workloads?

No, but you need PodDisruptionBudgets. Without PDBs, consolidation will evict pods without coordination. With PDBs, Karpenter respects them and waits for available replicas before moving pods.

Can I use Karpenter with spot and on-demand together?

Yes. That's the recommended configuration. Use requirements to specify both and let Karpenter prefer spot within your budget constraints.

How long does it take to see savings?

We saw cost reductions within the first billing cycle. Karpenter starts consolidating immediately. Within a week, our waste ratio dropped from 38% to 11%.

Is Karpenter hard to maintain?

Less maintenance than node groups, more than Cluster Autoscaler. The Karpenter controller updates itself automatically. You mostly need to tune provisioner settings quarterly as your workload profiles change.

What version of Kubernetes does Karpenter need?

Karpenter v0.37+ requires Kubernetes 1.24 or newer. Older clusters need upgrading first. We run 1.29 across all clusters and it works without issues.

Does Karpenter support GPU workloads?

Yes, but GPU configuration is manual. You need to specify instance types that offer GPUs and set the appropriate resource requests. Karpenter won't automatically bin-pack GPU workloads across nodes — that's still something you manage.


Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.

Free · No Commitment · 48-Hour Delivery

Get a free infrastructure audit

2-hour remote session. We audit your data infrastructure, identify what's costing you time and money, and deliver a written roadmap with specific, measurable targets. No pitch.

Book Your Free Audit
N
Nishaant Dixit
Founder & Lead Engineer at SIVARO

Building data-intensive systems since 2018. 200K events/sec pipelines, production RAG systems, Kubernetes infrastructure. LinkedIn →

Start a Project
Need help with infrastructure?

Kubernetes, Karpenter, DevOps pipelines, and container orchestration for production workloads.

Explore MVP to Production