Kubernetes Cluster Autoscaler vs Karpenter: When to Use Each (2026)

Your pods are pending. Your on-call engineer is getting paged. Somewhere in the chain between “I need more compute” and “compute is available,” something is too slow. That something is almost always node provisioning — and the tool you chose to manage it determines whether that delay is 4 minutes or 45 seconds. Node autoscaling is one of those infrastructure decisions that looks simple until you’re running it in production. Two schedulable pods sitting in Pending state doesn’t just mean a delayed deployment — it means latency spikes, dropped traffic, breached SLOs, and engineers debugging things that should have been invisible. At scale, it also means either burning money on over-provisioned nodes or gambling on under-provisioning at the worst possible moment. Cluster Autoscaler (CA) has been the default answer for years. Karpenter emerged from AWS in 2021, graduated to stable in 2023, and by 2025 had become the default recommendation for most AWS-native clusters. In 2026, both tools are mature, widely deployed, and genuinely good — but they solve the problem differently, and picking the wrong one for your environment has real consequences. This article is a deep technical comparison. It assumes you already know what Kubernetes is and have opinions about infrastructure. The goal is to give you a clear picture of how each tool works, where each one wins, and a decision framework you can actually use.

Karpenter vs Cluster Autoscaler: the short answer

Cluster Autoscaler scales node groups you defined in advance; Karpenter provisions individual nodes on demand, choosing the instance type itself. That single architectural difference drives everything else. Cluster Autoscaler adds nodes to an existing ASG or MIG, so provisioning takes roughly 4–8 minutes and your instance choice is fixed by whatever you put in the node group. Karpenter talks to the cloud provider API directly, bin-packs pending pods against the whole instance catalogue, and typically has capacity in 60–90 seconds — while consolidating underused nodes to cut cost. Use Cluster Autoscaler if you need mature multi-cloud support, you have strict node-group governance, or your capacity is reserved and homogeneous. Use Karpenter if you are on AWS (or now Azure), your workloads are heterogeneous, and you want faster scale-up plus automatic cost consolidation. Whether you phrase it “Cluster Autoscaler vs Karpenter” or the other way round, the decision comes down to three questions — cloud, workload diversity, and how much control you want over instance selection — and there is a full decision framework at the end of this article.

Why Node Autoscaling Is Hard

The fundamental tension in autoscaling is this: you want compute available before you need it, but you don’t want to pay for compute you’re not using. These goals are in direct conflict, and every autoscaling system is an attempt to find the least-bad trade-off. Without autoscaling, you’re doing one of two things:
  1. Over-provisioning — you run enough nodes to handle peak load at all times. Your average utilization sits at 20–30%, and you’re paying for the other 70–80% to sit idle.
  2. Under-provisioning — you run lean, and when traffic spikes, pods go Pending. Your SLOs breach. You get paged at 3am to manually scale.
A common failure mode with poorly tuned autoscaling is the “thundering herd at scale-up” pattern: HPA creates new pods faster than node autoscaling can provision capacity. The provisioning window matters. With CA and typical ASG-backed node groups on AWS, you’re looking at 4–8 minutes. With Karpenter, 60–90 seconds. At 100 RPS and a 3-minute window, that’s 18,000 requests under degraded conditions.

Cluster Autoscaler: How It Actually Works

Cluster Autoscaler is a Kubernetes-native project under the kubernetes/autoscaler repository, in production since 2016, supporting AWS, GCP, Azure, Alibaba, DigitalOcean, and more.

The Node Group Model

CA operates on node groups — ASGs on AWS, MIGs on GCP, VMSSs on Azure. CA’s job is to decide when to increase or decrease the desired capacity of these groups. CA does not provision individual nodes. It scales node groups, and the node group provisions nodes. This indirection adds latency and reduces flexibility.

Scale-Up: Detecting Unschedulable Pods

CA runs a control loop (default scan interval: 10 seconds). For each Pending pod with PodScheduled=False, CA simulates adding a node of each known node group type and checks if the pod would become schedulable. When a node group is selected, CA applies an expander to choose which group to scale:
  • least-waste — minimizes CPU/memory waste after scheduling (best default for cost)
  • most-pods — maximizes pods scheduled per scale-up operation
  • priority — lets you define ordering via ConfigMap
  • grpc — delegates to an external gRPC service
# Cluster Autoscaler deployment — AWS, production-tuned
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-autoscaler
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cluster-autoscaler
  template:
    metadata:
      labels:
        app: cluster-autoscaler
      annotations:
        cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
    spec:
      priorityClassName: system-cluster-critical
      serviceAccountName: cluster-autoscaler
      containers:
        - image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.36.1
          name: cluster-autoscaler
          resources:
            requests:
              cpu: 100m
              memory: 600Mi
            limits:
              cpu: 200m
              memory: 1Gi
          command:
            - ./cluster-autoscaler
            - --cloud-provider=aws
            - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster
            - --expander=least-waste
            - --balance-similar-node-groups=true
            - --scale-down-delay-after-add=10m
            - --scale-down-unneeded-time=10m
            - --scale-down-utilization-threshold=0.5
            - --max-graceful-termination-sec=600
            - --scan-interval=10s

Scale-Down: The Conservative Approach

A node is a scale-down candidate only if: – CPU and memory utilization (by requests) is below threshold (default: 50%) – All pods could be rescheduled elsewhere – No pod has cluster-autoscaler.kubernetes.io/safe-to-evict: "false" – The node has been underutilized for at least --scale-down-unneeded-time (default: 10m) This conservatism prevents churn — a feature, not a bug.

Karpenter: How It Actually Works

Karpenter was built by AWS and donated to the Kubernetes project in 2023, where it lives as a SIG Autoscaling subproject under kubernetes-sigs (it has no CNCF maturity level of its own); it reached GA (v1.0) in mid-2024. Providers exist for AWS (stable), Azure (stable), and GCP (beta).

The Core Insight: Bypass the Node Group

Karpenter calls the EC2 RunInstances API directly — no ASG involvement. This means: – Any instance type in a single request, without pre-configuring a node group – No intermediary: Karpenter → EC2 API → node joins cluster – Right-size nodes to exactly what workloads need, across the full instance catalog – Karpenter handles full node lifecycle, including termination

NodePool and EC2NodeClass

# EC2NodeClass — cloud-specific parameters
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  role: "KarpenterNodeRole-my-cluster"
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "my-cluster"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "my-cluster"
  blockDeviceMappings:
    - deviceName: /dev/xvda
      ebs:
        volumeSize: 50Gi
        volumeType: gp3
        encrypted: true
  metadataOptions:
    httpTokens: required
    httpPutResponseHopLimit: 1
---
# NodePool — intent and constraints
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general-purpose
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand", "spot"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64", "arm64"]
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["c", "m", "r"]
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ["5"]
        - key: karpenter.k8s.aws/instance-size
          operator: NotIn
          values: ["nano", "micro", "small", "medium", "large"]
      expireAfter: 720h
  limits:
    cpu: "1000"
    memory: 1000Gi
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 5m
    budgets:
      - nodes: "5%"
        schedule: "0 8 * * mon-fri"
        duration: 10h
      - nodes: "25%"

Just-in-Time Provisioning and Bin Packing

When pods go Pending, Karpenter watches the event (not polls) and immediately: 1. Collects all Pending pods 2. Simulates bin packing — fewest possible nodes across the full instance catalog 3. Selects instances that satisfy all pod requirements 4. Calls EC2 API to provision the optimal instance(s)

Disruption and Consolidation

Karpenter’s differentiated value: active cluster consolidation. It evaluates whether nodes can be removed by redistributing pods onto others, or replaced with a smaller instance type. A c5.4xlarge running 4 vCPU worth of pods gets replaced with a c5.xlarge. Teams commonly report 30–50% compute cost reduction. consolidationPolicy options: – WhenEmpty — only remove nodes with no workload pods (safest) – WhenEmptyOrUnderutilized — also replace underutilized nodes with smaller ones

Architecture Comparison

DimensionCluster AutoscalerKarpenter
Node provisioning modelScales node groups (ASG/MIG/VMSS)Direct cloud API, no node groups
Instance flexibilityPre-defined node group typesFull instance catalog at runtime
Scale-up triggerPolling (10s scan interval)Watch-based event (near-instant)
Scale-downRemoves underutilized nodesRemoves + consolidates + right-sizes
Spot handlingVia ASG + AWS Node Termination HandlerNative, first-class, no NTH needed
Configuration modelDeployment flagsDeclarative CRDs
Cloud supportAll major + on-premAWS (GA), Azure (stable), GCP (beta)
ConsolidationNoYes
Community maturityVery mature (since 2016)Mature (GA 2024)

Scaling Speed: The Numbers

Cluster Autoscaler on AWS (typical): 1. Pod Pending → CA scan detects (0–10s) 2. ASG UpdateAutoScalingGroup API call (~15–30s) 3. EC2 instance starts (1–2 min) 4. Node bootstrap + kubelet registration (30–60s) 5. Pod scheduled (5–10s) Total: 3–6 minutes (up to 12 min during high-demand periods) Karpenter on AWS (typical): 1. Pod Pending → watch event fires (~1s) 2. EC2 RunInstances API call (~2–3s) 3. EC2 instance starts (same hardware — 1–2 min) 4. Node bootstraps + Ready (30–60s) 5. Pod scheduled (~5s) Total: 90 seconds to 3 minutes

Cost Optimization: Where Karpenter Pulls Ahead

Right-sizing: CA requires pre-defined node groups. Karpenter selects the minimum viable instance for the pending workload from the full catalog. Consolidation vs scale-down: CA removes underutilized nodes. Karpenter replaces a large underutilized node with a smaller one that still fits all pods. This produces compounding savings over time. Spot handling: Karpenter receives EC2 interruption notices, pre-provisions a replacement, and drains the node — all within the 2-minute window. No AWS Node Termination Handler required. It also diversifies spot requests across instance types automatically to reduce simultaneous interruption risk.

What’s New in Karpenter v1.14 (July 2026)

If your mental model of Karpenter was formed around v1.0, three changes shipped in v1.14.0 (11 July 2026) are worth revisiting, because two of them close gaps that used to be genuine reasons to stay on Cluster Autoscaler. 1. Dynamic Resource Allocation (DRA) support. Karpenter now ships a DRA allocator: it understands ResourceClaim objects when deciding what to provision, including pod-level claims, and supports consumable capacity and partitionable devices. In practice this is the GPU story. Under the old model, “this pod needs a slice of an A100” was expressed through labels, taints and affinity rules, and the autoscaler could not reason about it properly — you pinned GPU workloads to a hand-built node group and accepted the waste. With DRA, the device requirement is a first-class scheduling input, so Karpenter can pick the right accelerator instance and pack partitionable devices instead of stranding a whole GPU per pod. If you run ML workloads, this is the release that matters. 2. The CapacityBuffer API (v1beta1). Karpenter’s great weakness was always the cold start: it is fast, but it still provisions after pods go Pending. CapacityBuffer lets you declare headroom that Karpenter keeps warm, which is the “overprovisioning with pause pods” hack that teams have been hand-rolling for years, now a supported API with its own status metrics. It directly narrows the gap against a deliberately over-provisioned Cluster Autoscaler node group. 3. The Balanced consolidation policy. Consolidation used to be a fairly blunt trade — pack tighter, accept more disruption. The new Balanced policy sits between aggressive consolidation and leaving nodes alone, and consolidateAfter now also applies to destination nodes during consolidation, which makes churn considerably more predictable. If you evaluated Karpenter, liked the cost numbers and rejected it because the disruption was too noisy for your workloads, that objection is worth re-testing.

Where that leaves the release line today: v1.14.1 (21 August 2026) is the current release and is tagged as an LTS line by the AWS provider, with support committed through July 2027; the previous LTS is v1.9.x. There is no v1.15 yet. If you are choosing a version to standardise on for the next year, v1.14 is the one — it has the DRA allocator, CapacityBuffer and the Balanced policy, and it will keep receiving patches after the interim minors are dropped.

Related reading: Kubernetes HPA memory examples.


What’s New in Cluster Autoscaler (2026)

It would be easy to read the section above as “Karpenter moves, Cluster Autoscaler stands still”. That is not what the release history says. CA tracks Kubernetes minors — 1.35.0 shipped in February 2026 and 1.36.0 in July 2026, with 1.36.1 the current patch — and two of the 2026 additions are direct answers to Karpenter’s headline features. 1. DRA support, including partitionable devices. Cluster Autoscaler can now simulate scheduling for pods that use ResourceClaims rather than the classic nvidia.com/gpu extended resource, and 1.36 added support for partitionable devices (the MIG-style “slice of an accelerator” case). It is still behind a feature flag and it still works at node-group granularity — CA can only add a node of a type you have already defined — but the “CA cannot reason about DRA at all” objection is gone. If you run GPU workloads on a non-AWS cloud, this matters more than anything Karpenter shipped. 2. CapacityBuffer v1beta1 — the same idea, on the CA side. 1.35 released a CapacityBuffer API for declaring warm headroom, now namespaced and integrated with ResourceQuotas so buffers respect the quotas you already have. This is the same problem Karpenter’s CapacityBuffer solves, arriving in the same year; the pause-pod overprovisioning hack is now a supported API on both sides of this comparison. 3. CapacityQuota and “salvo” scale-up (1.36). CapacityQuota is a CRD that caps the resources CA is allowed to scale up — a guard rail that used to require external tooling. The experimental --salvo-scale-up flag lets CA perform several scale-ups in a single loop instead of one per iteration (budgeted with --salvo-scale-up-budget), which directly attacks the “4-8 minutes” number in the scaling-speed section when many node groups need to grow at once. 4. Operational tuning. A separate --max-node-startup-time, --predicate-parallelism to run scheduler predicates on more threads (replacing --cluster-snapshot-parallelism), a “suspended” node state in the status ConfigMap, CSI volume-limit awareness during scale-up, and atomic size increases for Azure VMSS so a partially-fulfilled scale-up no longer leaves you with the wrong node count. --scale-down-enabled is deprecated in favour of the newer scale-down flags — check your Helm values before upgrading past 1.35. None of this changes the architecture: CA still scales node groups, not nodes. But if your reason for wanting Karpenter was DRA, warm capacity or scale-up throughput rather than instance flexibility, re-read the CA release notes before you migrate.

Multi-Cloud Support in 2026

CloudCluster AutoscalerKarpenter
AWS✅ Production-stable✅ Production-stable (reference impl.)
GCP✅ Production-stable⚠️ Beta (karpenter-provider-gcp)
Azure✅ Production-stable✅ Stable (karpenter-provider-azure)
Alibaba✅ Supported❌ No provider
DigitalOcean✅ Supported❌ No provider
On-premises / Cluster API✅ Supported❌ Not supported

Karpenter vs HPA, VPA and KEDA: Which Autoscaler Does What

A recurring confusion in the comparison searches: Karpenter is not an alternative to HPA or KEDA. They operate on different layers and are designed to run together. Pod autoscalers decide how many replicas you need; node autoscalers decide what hardware those replicas land on. Karpenter and Cluster Autoscaler only ever see the outcome of the pod autoscalers — pending pods.

So “KEDA vs Karpenter” and “HPA vs Karpenter” are not real choices. KEDA and HPA answer how many pods; Karpenter and Cluster Autoscaler answer how many nodes, and which ones. You will almost always run one from each row. The real comparison is HPA vs KEDA on the pod layer (KEDA when the signal is a queue, a topic or a schedule rather than CPU) and Karpenter vs Cluster Autoscaler on the node layer, which is what the rest of this article is about.

ComponentLayerWhat it changesInput signalScales to zero
HPAPodNumber of replicasCPU, memory, custom/external metricsNo (min 1)
KEDAPodNumber of replicas (drives an HPA underneath)Event sources: queue depth, Kafka lag, cron, 60+ scalersYes
VPAPodRequests and limits of each podHistorical usageN/A
Cluster AutoscalerNodeSize of predefined node groupsUnschedulable podsNode groups to 0
KarpenterNodeIndividual nodes and their instance typeUnschedulable pods + consolidationYes

The chain in practice

A queue backs up, KEDA sees the lag and raises the replica count, the new pods cannot be scheduled because the cluster is full, and Karpenter provisions a node that fits them. Every layer does its own job. The failure mode people hit is tuning only one of them: an HPA that scales aggressively on a cluster with a slow node autoscaler produces pods that sit pending for minutes, and the latency you were trying to fix stays exactly where it was.

Two pairings deserve care. HPA and VPA on the same metric fight each other — VPA raises requests, which lowers measured CPU utilisation, which makes HPA scale down; run VPA in Off or Initial mode if an HPA already targets CPU on that workload. And KEDA scaling to zero only works if the node autoscaler can drain the last node: with Karpenter, that is consolidation doing its job; with Cluster Autoscaler, you need the node group’s minimum set to 0. See HPA best practices for the pod-level half of this.

Replacing Cluster Autoscaler with Karpenter

If the goal is a straight replacement rather than coexistence, the order matters: install Karpenter with a NodePool that is restricted to the workloads you are moving, scale the Cluster Autoscaler node groups down as Karpenter takes over, and only then remove the Cluster Autoscaler deployment. Removing it first leaves the old node groups with nobody managing scale-down, and you pay for idle nodes until someone notices.


When Cluster Autoscaler Is Still the Right Choice

  1. Non-AWS environments — GCP, Alibaba, DigitalOcean, on-prem with Cluster API
  2. Existing node group architecture — significant investment in ASG design, compliance tooling
  3. Regulatory constraints — some frameworks require ASG-backed provisioning audit trails
  4. Cluster API / bare metal — CA is the only mature option
  5. Team familiarity and working-well CA deployment — migration cost may not justify benefit

When Karpenter Is the Right Choice

  1. AWS-native, cost optimization priority — right-sizing + consolidation = meaningful cost reduction
  2. Diverse and variable workloads — batch, spot, GPU, stateless APIs — Karpenter handles all with a few NodePools
  3. Spot-heavy clusters — native interruption handling, diversification, no NTH
  4. Declarative infrastructure-as-code culture — NodePools version cleanly in Git
  5. Low-latency scaling requirements — event-driven workloads, KEDA-triggered jobs, sharp traffic spikes

Running Both: Migration Path and Gotchas

Separating Responsibility

Use labels and taints to prevent CA and Karpenter from managing the same nodes:
# NodePool with taint — CA-managed pods won't tolerate this
spec:
  template:
    metadata:
      labels:
        provisioner: karpenter
    spec:
      taints:
        - key: karpenter.sh/provisioned
          value: "true"
          effect: NoSchedule

Gradual Migration

  1. Phase 1 — Karpenter manages spot/batch workloads. CA manages on-demand production nodes.
  2. Phase 2 — Migrate spot workloads fully. Remove AWS NTH.
  3. Phase 3 — Migrate on-demand. Reduce CA node group capacity gradually.
  4. Phase 4 — Decommission CA once all groups are empty.

Key Gotchas

  • Karpenter consolidation + permissive PDBsmaxUnavailable: 100% will cause disruptive consolidation. Audit PDBs before enabling WhenEmptyOrUnderutilized.
  • NodePool limits are hard stops — pods go Pending indefinitely at limit. Monitor utilization.
  • AMI drift@latest alias picks up new AMIs on new nodes. Consider pinning for strict change control.
  • Simultaneous scale-down conflicts — use strict label/taint segregation during migration.

Karpenter vs Cluster Autoscaler Cost: When the Savings Are Real

The number most often quoted for “Karpenter vs Cluster Autoscaler cost” is a 20-40% reduction in compute spend after migration. It is a real number — but it comes from a specific starting point, and it is worth being precise about where the money comes from, because two of the three sources are available to Cluster Autoscaler too. Where Karpenter’s savings actually come from:
  • Instance selection across the whole catalog. A pending pod that needs 3 vCPU and 12 GiB lands on the cheapest instance that fits it — possibly a type you would never have created a node group for. With CA you pay for the granularity of the node groups you happened to define. This is the source that CA structurally cannot match, and in heterogeneous clusters it is the largest one.
  • Active consolidation. Karpenter continuously replaces an underused large node with a smaller one that still fits every pod. CA’s scale-down is binary — a node is either below the utilisation threshold and removed, or left alone — so a cluster of 60%-utilised nodes never gets cheaper under CA and keeps shrinking under Karpenter.
  • Spot without ceremony. Diversified spot requests, interruption handling and replacement provisioning are built in. CA can run spot node groups, but the diversification and the graceful replacement are on you (or on the Node Termination Handler).
Where Cluster Autoscaler is just as cheap:
  • Homogeneous, reserved capacity. If your fleet is 90% one instance family covered by Savings Plans or Reserved Instances, the cheapest node is the one you already committed to. Karpenter’s catalog-wide bin packing has nothing to optimise, and its consolidation can actually hurt by moving load off committed capacity onto on-demand instances unless you constrain the NodePool tightly.
  • Steady-state workloads. Consolidation saves money on clusters whose shape changes. A cluster that runs the same 40 pods all day at stable requests has no fragmentation to recover.
  • Well-tuned least-waste with a small set of right-sized node groups. Most of the overprovisioning CA gets blamed for is a node-group design problem — three sizes per family, least-waste as the expander and --scale-down-utilization-threshold raised from the default 0.5 close most of the gap on simple clusters.
The honest rule of thumb: the more heterogeneous and bursty the workloads, the larger the gap in Karpenter’s favour. Batch, CI runners, spot-tolerant services and mixed GPU/CPU fleets are where the 30% figures come from. A stable microservice platform on reserved instances should expect single digits, and the migration effort described below may not pay for itself on cost alone — do it for the provisioning latency and the operational model, not the invoice.

Decision Framework

FactorCluster AutoscalerKarpenter
Cloud supportAll clouds + on-premAWS (GA), Azure (stable), GCP (beta)
Provisioning speed4–8 minutes60–120 seconds
Instance flexibilityNode group pre-config requiredFull catalog, runtime selection
Cost optimizationScale-down onlyScale-down + consolidation + right-sizing
Spot integrationVia ASG + NTHNative, first-class
Operational complexityLowerModerate
Cluster API / bare metalYesNo
ConsolidationNoYes
Running on AWS?
├── No → Azure? → Karpenter (stable) or CA
│        GCP?   → CA or GKE NAP (preferred)
│        Other  → Cluster Autoscaler
│
└── Yes → Hard regulatory constraints on non-ASG provisioning?
          ├── Yes → Cluster Autoscaler
          └── No → Cost optimization priority or diverse workloads?
                   ├── Yes → Karpenter
                   └── No → Either (flip for team preference)

Frequently Asked Questions

Is Karpenter a drop-in replacement for Cluster Autoscaler?

No. Different configuration model, different concepts. Migration requires re-expressing node group config as NodePools/NodeClasses, auditing PDBs, and running both in parallel. Budget at least a sprint for a medium-sized cluster.

Can I run Karpenter on self-managed Kubernetes (not EKS)?

Yes, but non-trivial. Karpenter requires IAM credentials (IRSA or equivalent) to call EC2 APIs. On self-managed clusters, this requires more setup than on EKS where IRSA is built-in.

How does Karpenter interact with HPA and VPA?

No conflict. HPA creates pods u2192 pods go Pending if insufficient nodes u2192 Karpenter provisions nodes u2192 pods scheduled. VPA adjusts pod resource requests, which Karpenter uses as inputs for bin packing.

What happens when Karpenter itself goes down?

Existing nodes and pods continue normally. New pods requiring provisioning go Pending until Karpenter recovers. Scale-down and consolidation pause. Deploy multiple replicas with leader election for production.

Does Karpenter support GPU nodes?

Yes. GPU instance types (p3, p4, g4, g5) can be included in NodePool requirements. Create dedicated NodePools with appropriate taints for GPU-requesting pods.

How does Karpenter handle AMI updates?

The expireAfter field forces node rotation. When a node expires, Karpenter pre-provisions a replacement with the latest AMI per EC2NodeClass, then drains and terminates the old node — a rolling AMI update mechanism without additional tooling.

Is Cluster Autoscaler still actively maintained?

Yes. CA remains under active development in kubernetes/autoscaler, with releases tracking Kubernetes minor versions. It is not being deprecated. For non-AWS environments and working CA deployments, it remains a fully supported and rational choice.

Is Karpenter cheaper than Cluster Autoscaler?

Usually, but not always. Karpenter saves money through three mechanisms: choosing the cheapest instance from the whole catalog for each pending workload, continuously consolidating underused nodes into smaller ones, and handling spot diversification and interruptions natively. On heterogeneous, bursty clusters this adds up to 20-40% less compute spend. On a homogeneous fleet covered by Reserved Instances or Savings Plans, with steady workloads and well-designed node groups using the least-waste expander, Cluster Autoscaler is just as cheap and the migration rarely pays for itself on cost alone.

Karpenter vs Cluster Autoscaler: Quick Decision Recap

Searching for Karpenter vs Cluster Autoscaler? The one-paragraph version: choose Karpenter on AWS when provisioning speed (60–90 seconds vs 4–8 minutes), instance-type flexibility and cost consolidation matter. Choose Cluster Autoscaler when you need multi-cloud portability, you already operate stable node groups, or your platform depends on the node-group model (compliance-pinned AMIs, strict capacity planning).

Related reading: GPU scheduling with Dynamic Resource Allocation.

Related reading: Kamal vs Kubernetes.

Related reading: EKS Auto Mode.

Both can coexist during a migration: run Cluster Autoscaler for existing node groups while Karpenter handles new dynamic capacity, then consolidate once you trust the disruption behavior.


Tested against Kubernetes 1.31–1.36. Karpenter v1.x API (GA; v1.14.1 LTS is current). Cluster Autoscaler 1.36.x. AWS provider examples; Azure and GCP provider details may differ. Last reviewed September 2026.