TL;DR: Traditional Cluster Autoscaler can only add nodes from predefined node groups, so a pod needing 2 vCPU on an m5.xlarge node group gets a 4 vCPU / 16 GB node — half wasted from boot. Karpenter (free, open-source, AWS-built) throws node groups away: for each unschedulable pod it picks the cheapest of hundreds of instance types that fits, prefers Spot, launches in seconds, and consolidates underused nodes continuously. On any real-scale EKS cluster that's 40–60% off with no app changes — the largest single cost lever. The one prerequisite: eviction hygiene.
The numbers
- The win is eliminating the "round up to the node group's instance type" tax — Karpenter matches per-pod requirements to the cheapest fit (a t3a.medium here, an r6i.large there, a c6g Spot for batch), so bin-packing improves dramatically.
- Spot-first by default (up to 90% off, On-Demand fallback), with EventBridge-driven cordon/drain on the 2-minute interruption notice; diversify across many types to cut interruption frequency.
- Consolidation runs continuously — reschedules pods off underused nodes and terminates them, so the cluster stays cheap as pods churn.
- Field examples: a mixed cluster put web on stable On-Demand and bursty batch on a scale-from-zero Spot NodePool for 70–80% off batch; a 40-microservice cluster of varied pod shapes saw 40–60% off in the first month, no app changes.
Do this
- Install via Helm and tag subnets/security groups so Karpenter knows where to launch.
- Define one broad NodePool to start — allow many instance families, both Spot and On-Demand, and include arm64 so Karpenter picks Graviton when it wins on price.
- Cordon and drain managed node groups gradually so workloads migrate onto Karpenter-provisioned nodes; watch consolidation rebalance in the logs.
- Split into 2–3 NodePools — general (mostly Spot, broad choices), stateful/latency-sensitive (On-Demand only, via node selectors), and GPU if needed.
- Fix eviction hygiene before flipping the switch — PodDisruptionBudgets, clean SIGTERM handling, and a reasonable
terminationGracePeriodSeconds(Kubernetes best practice regardless).
Gotchas
- Consolidation moves pods — that's the mechanism, not a bug; a disruptive eviction means missing PDBs/SIGTERM hygiene, not a reason to disable it.
- Watch EC2 quotas — Karpenter can launch 20 nodes in a minute during a spike and will silently stall on low vCPU/instance-type quotas; pre-request increases for your allowed families.
- Spot is still Spot — pin workloads that truly can't tolerate interruption (single-replica stateful DBs without failover) to an On-Demand NodePool.
- Mindset shift — you stop picking instance types and start describing constraints; the savings come precisely because Karpenter has no comfort zone.
Skip this if
- The cluster is tiny (2–3 nodes) — the operational overhead outweighs the savings.
- Hard compliance requires pre-warmed, specific instance types, or the environment forbids any pod disruption — Karpenter's dynamism and consolidation conflict with that. For the Spot model it relies on, see Spot Instances; let it add arm64 with Graviton, and consider Bottlerocket OS as the node OS for smaller, more secure hosts.