Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

AWS EKS Consulting

Karpenter or Cluster Autoscaler: Scaling EKS Capacity Efficiently

We choose and configure Karpenter or Cluster Autoscaler for your EKS workloads. Karpenter provisions right-sized nodes on demand and consolidates idle ones, Cluster Autoscaler scales existing node groups. We set limits, Spot policy and disruption rules so scaling saves money without hurting availability.

Key takeaways

  • Karpenter picks instance types per pending pod and removes underused nodes, which usually fits variable workloads better than fixed node groups.
  • Cluster Autoscaler is still reasonable for stable, node group based clusters that value simplicity.
  • Scaling only saves money if pod requests are realistic, so we review requests before tuning the autoscaler.
  • Spot is used for interruption tolerant workloads, with on-demand capacity kept for the rest.
  • Disruption budgets and PodDisruptionBudgets stop consolidation from causing outages.

Scaling is where EKS money is won or lost

Compute is usually the largest line on an EKS bill, and most of the waste comes from nodes that are bigger or more numerous than the workload needs. Autoscaling should fix that, but a poorly configured autoscaler can instead cause pending pods during traffic spikes, or evict the wrong things at the wrong moment.

This page describes how we select and configure node autoscaling as part of AWS EKS consulting. The financial side is covered in cost analysis and optimisation, and the broader tactics in our guide to EKS cost optimisation.

What good looks like

  • Pods that need capacity get it quickly, and capacity that is idle goes away.
  • Instance types are chosen from a sensible set, not hard-coded to one family.
  • Spot is used where interruption is acceptable and not elsewhere.
  • Scale-down never breaks availability because disruption budgets are respected.
  • You can see scaling decisions in dashboards and logs.

Karpenter or Cluster Autoscaler

QuestionKarpenterCluster Autoscaler
How does it add nodes?Launches EC2 instances matching pending pod needsRaises desired size of a node group
Instance flexibilityHigh, picks from many types per requestLimited to types in each group
ConsolidationBuilt in, replaces or removes underused nodesRemoves empty or underused nodes only
Setup effortNodePools, EC2NodeClass, IAM and queue setupFamiliar, tied to Auto Scaling groups
Best fitVariable load, Spot, mixed shapesStable load, small number of node groups

We recommend Karpenter for most new production clusters because it reduces the tuning that fixed node groups need. We recommend Cluster Autoscaler when the team already runs it well and the workload is predictable. We do not recommend switching purely for novelty.

A representative Karpenter configuration

Karpenter uses a NodePool to describe what it may launch and an EC2NodeClass to describe how. The example below allows a Spot and on-demand mix across several families, caps total capacity and enables consolidation. API versions change between Karpenter releases, so confirm against the version you install.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: general
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["c", "m", "r"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
      expireAfter: 720h
  limits:
    cpu: "400"
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
    budgets:
      - nodes: "10%"

The limits block is a cost safety net: it stops a runaway deployment from launching unlimited nodes. The budgets entry controls how many nodes may be disrupted at once.

Spot without drama

Spot saves money but can be reclaimed with short notice. Our rules of thumb:

  • Allow many instance types and sizes so capacity pools are deep.
  • Run at least two replicas, spread across zones, for any service on Spot.
  • Keep databases, singletons and long-running non-resumable jobs on on-demand nodes using separate NodePools and taints.
  • Handle interruption gracefully: Karpenter reacts to interruption events via an SQS queue, and applications need sensible termination grace periods.

Requests first, autoscaler second

An autoscaler schedules on pod requests, not actual usage. If every pod asks for far more than it uses, the cluster fills with reserved but idle capacity, and no scaler can fix that. Before tuning, we compare requests with measured usage and adjust. Pair this with the Horizontal Pod Autoscaler for replica scaling, and consider event-driven scaling for queue workers. Background on resource requests and limits explains why this matters.

Separating workload classes

One NodePool rarely suits everything. We usually define a small number of classes and let scheduling rules steer pods to them. A general class carries stateless services on a Spot and on-demand mix. A protected class on on-demand capacity carries databases, singletons and anything that cannot tolerate interruption, and is tainted so only workloads that tolerate the taint land there. A specialised class carries GPU or high-memory pods, with tight limits so a mistaken deployment cannot run up a bill.

# pod spec fragment for a workload that must stay on protected capacity
tolerations:
  - key: "workload-class"
    operator: "Equal"
    value: "protected"
    effect: "NoSchedule"
nodeSelector:
  workload-class: protected

Keeping the number of classes small matters. Each extra class is another set of limits and disruption rules to understand, and capacity in many small pools packs less efficiently than capacity in a few shared ones.

A worked example: a slow scale-up

A common complaint is that pods wait too long during a traffic burst. We trace the delay in stages: how long until Karpenter notices the pending pod, how long until the instance launches, how long until the node joins and becomes ready, and how long until the image pulls. The slow stage differs between clusters. If image pulls dominate, smaller images or a cache help more than any autoscaler setting. If launches fail, the cause is often an instance quota or an unavailable capacity pool, which broader instance choices solve.

Failure modes we plan for

  • Consolidation churn: aggressive settings keep replacing nodes. We tune consolidateAfter and budgets, and protect sensitive pods with annotations or PodDisruptionBudgets.
  • Pending pods during bursts: caused by tight limits, zone constraints or instance quotas. We review EC2 service quotas ahead of launch.
  • IP exhaustion: many small nodes consume subnet IPs. This ties back to architecture and subnet sizing.
  • Karpenter as a single point: it needs to run on capacity it does not manage itself. We place it on a small stable node group.
  • Slow image pulls: new nodes feel slow when images are large. We discuss image size and caching.

How it is delivered

We deploy the autoscaler with Terraform and Helm, configured through code, with test scenarios documented. Your team receives guidance on adding a NodePool, reading Karpenter logs and changing limits. If you run on Terraform modules, the IAM roles, queue and instance profile are part of the same module set.

How to measure it

Watch pending pod duration, node utilisation (requested versus allocatable), the share of capacity on Spot, interruption counts and provisioning time from pending to ready. Combine these with a cost view in Prometheus and Grafana. If utilisation stays low after tuning, the usual culprit is oversized requests rather than the scaler. For help diagnosing yours, book a consultation.

References

How we deliver it

  1. 01

    Profile the workload

    We look at pod requests, real usage, burst patterns, startup times and tolerance for interruption.

  2. 02

    Pick the autoscaler

    Karpenter or Cluster Autoscaler is chosen on fit, team familiarity and risk, with the reasoning written down.

  3. 03

    Define capacity classes

    NodePools or node groups are created for system, general, Spot and special hardware workloads.

  4. 04

    Set guardrails

    CPU and memory limits, allowed instance families, disruption budgets and expiry settings are configured.

  5. 05

    Test scaling behaviour

    We run scale-up, scale-down, Spot interruption and node replacement tests in a non-production cluster.

  6. 06

    Monitor and tune

    Dashboards track pending pods, node utilisation and provisioning latency, and settings are refined after real traffic.

Tools and technologies

KarpenterCluster AutoscalerEC2 SpotAmazon EKSHorizontal Pod AutoscalerKEDAAWS Node Termination HandlerPrometheusGrafanaTerraform

Frequently asked questions

What is the difference between Karpenter and Cluster Autoscaler?
Cluster Autoscaler adjusts the size of pre-defined node groups when pods are pending. Karpenter watches pending pods and launches nodes of suitable size and type directly, without node groups, then consolidates or removes nodes that are underused. Karpenter is generally faster and more flexible, with a bit more to learn.
Is Karpenter better than Cluster Autoscaler?
Often, for variable workloads and cost control, but not always. If your cluster is stable, uses a few node groups and your team is happy, Cluster Autoscaler works well. We recommend Karpenter when instance diversity, Spot use or fast scale-up matter.
Is it safe to run production on Spot instances?
It can be, for workloads that tolerate interruption: stateless services with several replicas, workers and batch jobs. Use multiple instance types, handle the two-minute interruption notice, and keep critical or single-replica workloads on on-demand capacity.
Why is my cluster not scaling down?
Common causes are pods without controllers, restrictive PodDisruptionBudgets, local storage, safe-to-evict annotations or DaemonSets and system pods placed badly. We trace the blocking pods and fix the cause rather than loosening safety settings.
Does Karpenter work with Fargate?
Fargate pods are scheduled onto AWS-managed capacity, so Karpenter does not provision nodes for them. Many clusters run Karpenter for ordinary workloads and Fargate for selected namespaces. Karpenter itself usually runs on a small managed node group or on Fargate.

Talk to an engineer about karpenter vs cluster autoscaler

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.