cd /news/artificial-intelligence/karpenter-best-practices-10-tips-for… · home topics artificial-intelligence article
[ARTICLE · art-123182] src=cast.ai ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

Karpenter Best Practices: 10 Tips for Production Clusters

CAST AI's guide to Karpenter best practices for production clusters on Amazon EKS details 10 configuration tips, including running the controller on dedicated nodes, using mutually exclusive NodePools, setting resource limits, wiring the SQS interruption queue, pinning AMIs, and using disruption budgets. The guide emphasizes that near-default configurations lead to predictable failures such as unwanted pod restarts, Spot interruptions, and runaway provisioning, and provides v1 API YAML examples targeting Amazon EC2.

read19 min views3 publishedSep 4, 2026
Karpenter Best Practices: 10 Tips for Production Clusters
Image: Cast (auto-discovered)

You deployed Karpenter, watched it scale your Amazon EKS cluster in seconds, and assumed the hard part was done. Then consolidation fired at 2 PM on a Tuesday, restarted pods your users were actively using, and your SLO alert fired. Or a Spot interruption hit before Karpenter could drain the node gracefully, because the SQS queue was never wired up. Or someone pushed a deployment with inflated resource requests and Karpenter provisioned 40 nodes in three minutes.

These are not edge cases. They are the predictable result of near-default configuration in a real production environment. This guide covers the Karpenter best practices that prevent those failures, with production-ready v1 API YAML throughout. All examples target Amazon EC2 as the cloud provider using the karpenter.k8s.aws API group. If you have just started with Karpenter, begin with our guide on what is Karpenter before continuing here.

Key Takeaways #

  • Run the Karpenter controller on a dedicated managed node group it cannot disrupt, or on AWS Fargate.
  • Use mutually exclusive NodePools with distinct taints to enforce workload isolation and enable team-level cost attribution.
  • Set spec.limits.cpu andspec.limits.memory on every NodePool to prevent runaway provisioning from billing surprises.
  • Wire the SQS interruption queue before running Spot workloads. Without it, Karpenter cannot drain nodes proactively on interruption.
  • Pin AMIs in production using a versioned alias (e.g., al2023@v20240219 ), not@latest .
  • Use WhenEmptyOrUnderutilized for consolidation (renamed in v1) and freeze disruptions during peak hours with disruption budgets.
  • Place expireAfter inspec.template.spec , not inspec.disruption . This location changed in v1.

Run Karpenter on Dedicated Nodes #

If your cluster is running Cluster Autoscaler, disable or remove it before enabling Karpenter. Running both simultaneously causes conflicting scale-down decisions. Karpenter and Cluster Autoscaler are not designed to coexist on the same node pools.

When configuring Karpenter for production, start with the official Helm chart from public.ecr.aws/karpenter/karpenter. To install Karpenter, run helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter against your target namespace. Running the controller on EKS means you must create an EKS managed node group for it before deploying any workloads — the controller needs a stable landing zone that is never disrupted.

If the Karpenter controller runs on nodes managed by Karpenter, a consolidation event can evict the controller itself mid-operation. The result: your kubernetes cluster loses its ability to provision new capacity until the pod reschedules on whatever remains. This circular dependency is the most common cause of the “Karpenter went quiet” incident pattern.

There are two reliable isolation strategies. First, run the controller on AWS Fargate using a Fargate profile scoped to the karpenter namespace. Second, run it on a dedicated managed node group carrying a taint of karpenter.sh/controller:NoSchedule, then add the matching toleration to the Karpenter deployment only. Either approach ensures the controller survives any consolidation event affecting the rest of the cluster.

For AWS EKS 1.24 and later, Pod Identity is the preferred mechanism for granting IAM roles to the Karpenter controller. IRSA (IAM Roles for Service Accounts) also works and remains supported. Both are valid, but Pod Identity simplifies role association and reduces the annotation overhead on service accounts.

Design Mutually Exclusive NodePools #

When multiple NodePools can satisfy the same pod’s workload requirements, Karpenter selects the pool with the highest spec.weight. If weights are equal, selection is non-deterministic. Without explicit isolation, workloads land in unpredictable pools, and cost attribution across different teams becomes guesswork. At 500 nodes, that ambiguity produces scheduling behavior that is genuinely difficult to debug.

Use distinct taints per NodePool to enforce isolation by default. Pods without the matching toleration simply cannot land on those nodes. When pools need to overlap intentionally, use spec.weight to establish explicit priority.

Example: NodePool with team isolation taint (v1 API)

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: frontend
spec:
  template:
    metadata:
      labels:
        billing-team: frontend
    spec:
      taints:
        - key: team
          value: frontend
          effect: NoSchedule
      expireAfter: 720h
      terminationGracePeriod: 24h
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
    budgets:
      - nodes: "10%"
  limits:
    cpu: "500"
    memory: 2000Gi

Teams that need this pool add the matching toleration to their pod specs. Everything else schedules elsewhere. This pattern also makes resource allocation transparent: you can tie NodePool labels to your billing pipeline directly.

Set Resource Limits on Every NodePool #

Without resource limits, a misconfigured deployment, a runaway HPA, or an autoscaling bug can provision hundreds of worker nodes before any billing alert fires. NodePool limits are a provisioning guard that is independent of your cloud cost alerts. Note that limit checking is eventually consistent: during rapid scale-outs, provisioning can briefly exceed the configured threshold before Karpenter reconciles.

Set spec.limits.cpu and spec.limits.memory on every NodePool. When Karpenter reaches the limit, it stops provisioning and pending pods remain unscheduled until capacity frees up. Size limits to 110-120% of expected peak load. That margin prevents artificial ceilings from blocking legitimate scaling while still catching runaway provisioning early.

spec:
  limits:
    cpu: "1000"
    memory: 4000Gi

This is one of the simplest Karpenter configuration steps and one of the most frequently skipped. Don’t skip it.

Enable Spot Interruption Handling via SQS, Not Node Termination Handler #

Spot instances offer significant savings, but the savings only hold if interruptions are handled gracefully. Without the SQS integration, Karpenter only learns of a Spot interruption when the node disappears from the Kubernetes API, which is often too late for workloads requiring graceful connection draining or checkpoint saves.

Why SQS beats Node Termination Handler

Karpenter supports native Spot interruption handling through SQS. When the SQS queue is configured via --interruption-queue, Karpenter receives the EC2 Spot Instance Interruption Warning through EventBridge up to two minutes before the node is reclaimed. Karpenter uses that window to cordon and drain proactively. The Node Termination Handler (NTH) that predates Karpenter creates a worse outcome: it races Karpenter’s own interruption handling to drain the same node, leaving pods in indeterminate states. To enable interruption handling correctly, remove NTH from the equation entirely.

What to wire up

Create an SQS queue and five EventBridge rules that forward the following events to it:

  • EC2 Spot Instance Interruption Warning
  • EC2 Instance Rebalance Recommendation
  • EC2 Instance State-change Notification
  • AWS Health Event (source: aws.health )
  • EC2 Capacity Reservation Instance Interruption Warning

The Karpenter getting-started guide includes a CloudFormation template that creates the SQS queue and all five EventBridge rules in a single stack. Use it as your starting point.

Reference: https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/

Reference the queue in the Karpenter controller configuration via --interruption-queue or the INTERRUPTION_QUEUE environment variable. The queue must be in the same AWS region as your cluster. The Karpenter controller IAM role requires sqs:ReceiveMessage, sqs:DeleteMessage, and sqs:GetQueueUrl on the queue resource.

For more on Karpenter and Spot instances, including cost modeling and real-world interruption rates by region, see our dedicated guide.

Pin AMIs in Production #

Using @latest in your EC2NodeClass means every node Karpenter launches pulls the current AMI at that moment. During an incident, when Karpenter is replacing nodes rapidly, @latest can introduce an untested kernel or kubelet version mid-recovery. That turns a capacity problem into a software compatibility problem. AMI drift across a cluster also makes debugging subtle node-level issues significantly harder when nodes were provisioned weeks apart.

Production vs. staging AMI strategy

Pin to a specific alias version for production EC2NodeClasses. Use @latest only in dev or staging, where you want to test incoming AMI changes before promoting them. Karpenter’s built-in drift detection then rolls nodes in a controlled way once you update the pinned version intentionally.

apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: production
spec:
  amiFamily: AL2023
  amiSelectorTerms:
    - alias: al2023@v20240219   # Pinned version for production
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"
  role: "KarpenterNodeRole-${CLUSTER_NAME}"
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: staging
spec:
  amiFamily: AL2023
  amiSelectorTerms:
    - alias: al2023@latest      # Always current, for pre-production testing
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}"
  role: "KarpenterNodeRole-${CLUSTER_NAME}"

Note: In Karpenter v1, amiSelectorTerms is a required field. Omitting it is a validation error. Drift detection is stable and enabled by default in v1; do not add --feature-gates Drift=true to your controller arguments, as that flag was removed.

Maximize Instance-Type Diversity for Spot #

Spot availability ties to individual instance types within specific availability zones. A NodePool restricted to m5.xlarge and m5.2xlarge competes in exactly two Spot capacity pools. When those pools tighten during a regional capacity event, Karpenter falls back to on-demand instances or fails to provision entirely. That is the leading reason Spot adoption stalls at scale.

Use category requirements, not explicit lists

Use category-level requirements instead of explicit instance-type lists. This exposes a broader set of instance types across families and generations, maximising Spot availability:

requirements:
  - key: karpenter.k8s.aws/instance-category
    operator: In
    values: ["c", "m", "r"]
  - key: karpenter.k8s.aws/instance-generation
    operator: Gte
    values: ["3"]
  - key: karpenter.sh/capacity-type
    operator: In
    values: ["spot"]

Additionally, diversity matters for Spot-to-Spot consolidation. For single-node (1-to-1) replacement, Karpenter requires at least 15 instance types priced lower than the current running Spot instance. Fewer alternatives produces an Unconsolidatable event for that candidate. This 15-type minimum does not apply to multi-node consolidations.

SpotToSpotConsolidation is still Alpha and disabled by default. Enable it via Helm values:

controller:
  featureGates:
    spotToSpotConsolidation: true

Or pass --feature-gates SpotToSpotConsolidation=true as a controller argument. Understand the trade-off: enabling this increases consolidation churn on Spot fleets, which works well for stateless workloads but adds risk for stateful ones.

Configure Consolidation and Disruption Budgets Correctly #

Karpenter’s default disruption budget allows up to 10% of managed nodes to be voluntarily disrupted simultaneously. Without custom budgets, consolidation runs during business hours, and mid-day pod restarts are indistinguishable from application errors until you trace the timeline. Disruption budgets give you control over when voluntary disruptions happen and how many nodes are affected at once.

Consolidation policy naming in v1

In Karpenter v1, the consolidation policy is WhenEmptyOrUnderutilized. The earlier name WhenUnderutilized was renamed. Update your manifests before upgrading to v1, or the validation webhook will reject them.

Freeze disruptions during peak hours

Use budget schedules to protect peak traffic windows. Setting nodes: "0" freezes all voluntary disruptions, including consolidation and drift, during the protected period. Budget schedules evaluate in UTC, so adjust cron expressions for your local business hours:

spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
    budgets:
      - schedule: "0 9 * * mon-fri"  # Monday-Friday, 09:00 UTC
        duration: 8h
        nodes: "0"                   # No voluntary disruptions during business hours
      - nodes: "10%"                 # Default outside protected window

For consolidateAfter, tune based on workload type: 5 minutes for batch workloads where pod restarts are cheap, and 10 minutes or longer for stateful services. At scale, a 500-node cluster with many underutilized nodes can trigger sustained disruption cycles lasting hours if consolidateAfter is too aggressive.

Watch karpenter_voluntary_disruption_decisions_total in Prometheus to confirm that budget windows suppress disruptions during the protected hours you configured. This metric is stable in Karpenter v1.

Set Node Expiry to Enforce AMI Freshness #

Long-lived nodes accumulate kernel drift, unpatched CVEs, and configuration state that was never intended to persist. In a kubernetes cluster running for months without rolling replacements, some nodes carry materially different software stacks than freshly launched ones. That complicates both incident response and security audits. Node expiry is the production-safe mechanism for enforcing rolling replacement on a schedule, rather than waiting for a manual process or a crisis.

v1 API change: expireAfter moved to spec.template.spec

In Karpenter v1, expireAfter lives in spec.template.spec, not in spec.disruption. This is a breaking change from earlier API versions. Additionally, v1 introduces terminationGracePeriod in the same location. The maximum node lifetime equals the sum of the two values: once expireAfter elapses, Karpenter begins draining the node and allows up to terminationGracePeriod for pods to exit before forceful termination.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      expireAfter: 720h           # 30-day rolling replacement
      terminationGracePeriod: 24h # Hard deadline after expiry begins
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 5m
    budgets:
      - nodes: "10%"
  limits:
    cpu: "1000"
    memory: 1000Gi

Expiration is a forceful disruption method. Karpenter begins draining expired nodes immediately and does not rate-limit via disruption budgets. PDBs are respected during draining, but misconfigured PDBs or karpenter.sh/do-not-disrupt annotations can block draining indefinitely, so audit both before relying on expiry.

In clusters using multiple NodePools, stagger expiry windows. For example, set 720h for stable API workload pools and 360h for batch processing pools. Uniform expiry values create synchronized replacement waves that spike EC2 API rate limits at the same time.

Use the do-not-disrupt Annotation Strategically #

Karpenter’s consolidation and drift mechanisms will voluntarily disrupt any node unless configured otherwise. The karpenter.sh/do-not-disrupt annotation protects against voluntary disruption only. Expiration, Spot interruption, and manual node deletion bypass it entirely.

Apply the annotation to pods where mid-run disruption causes data loss or unacceptable cold-start latency, particularly ML training jobs and data pipeline workers:

apiVersion: batch/v1
kind: Job
metadata:
  name: ml-training
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

Time-limited protection and edge cases

The annotation also accepts Go duration strings (e.g., "30m") to set a time-limited protection window instead of permanent protection. This works well for jobs with a known maximum runtime.

However, there is an important edge case: if terminationGracePeriod is configured on the NodePool, Karpenter can still disrupt an annotated pod via drift once the grace period expires, even if a PDB would otherwise block it. Do not rely solely on do-not-disrupt for indefinite protection when terminationGracePeriod is set.

Apply the annotation selectively. Annotating all production pods defeats consolidation and leads to node sprawl that grows silently. Audit annotation coverage regularly:

kubectl get pods -A -o json | jq '.items[] | select(.metadata.annotations["karpenter.sh/do-not-disrupt"] == "true") | .metadata.name'

When protected pods exceed 20-30% of your total workload, consolidation efficiency degrades enough to offset the savings the NodePool was designed to capture. Review protected workloads each quarter and remove the annotation from jobs where application-level checkpointing now handles mid-run interruptions safely.

Monitor with Prometheus: The Metrics That Actually Matter #

Karpenter exposes its metrics at karpenter.kube-system.svc.cluster.local:8080/metrics. Note the namespace: kube-system, not a dedicated karpenter namespace. Scrape this endpoint with Prometheus and build alerts around the metrics that surface real problems, not just activity.

Stable metrics for production alerting

Use only stable metrics for production alerts. Alpha metrics can be removed or renamed between releases without warning. The following are stable in Karpenter v1:

  • karpenter_pods_startup_duration_seconds : Time from pod creation to running. Alert when p99 exceeds your SLO. (This is the stable metric;karpenter_pods_provisioning_startup_duration_seconds is Alpha.)
  • karpenter_voluntary_disruption_decisions_total : Counts disruption decisions by reason ( consolidation ,drift ,expiration ). A spike inconsolidation decisions during business hours indicates a misconfigured disruption budget.
  • karpenter_nodeclaims_terminated_total : Alert on high termination rates. Counts all NodeClaim terminations by nodepool, capacity type, and zone. A spike indicates rapid consolidation, expiration, or Spot interruptions. Distinguish the cause by cross-referencingkarpenter_voluntary_disruption_decisions_total (consolidation/drift) and your SQS interruption queue metrics.

Alpha metrics (useful but subject to change)

  • karpenter_nodepools_usage : Tracks CPU and memory usage against your NodePool limits. Useful for capacity ratio alerting, but currently Alpha stability.
  • karpenter_nodepools_limit : The configured limits for each NodePool, used as the denominator in capacity ratio alerts. Also currently Alpha stability.

Example Prometheus alerting rule

Note: karpenter_nodepools_usage and karpenter_nodepools_limit are currently Alpha stability. They are useful for observability but pin your Karpenter version when using them in production alerts.

groups:
  - name: karpenter
    rules:
      - alert: KarpenterNodePoolNearLimit
        expr: |
          karpenter_nodepools_usage{resource="cpu"}
          / karpenter_nodepools_limit{resource="cpu"} > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "NodePool {{ $labels.nodepool }} CPU usage above 80%"

      - alert: KarpenterNodeClaimTerminations
        expr: increase(karpenter_nodeclaims_terminated_total[10m]) > 5
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "High NodeClaim termination rate on {{ $labels.nodepool }}"
          description: "More than 5 NodeClaims terminated in 10 minutes. Investigate consolidation, expiry, or interruption activity."

For Kubernetes autoscaling in general, the same principle applies: alert on outcomes (pod startup latency, pending pod count) rather than only on autoscaler activity. Activity without outcome impact rarely needs a page.

Taking Karpenter Further with Cast AI #

Following these practices gets your Karpenter setup to a defensible production baseline. However, several challenges remain outside Karpenter’s scope: rightsizing pod resource requests, predicting Spot interruptions before they happen, and migrating stateful workloads to Spot without downtime.

Kubernetes cost optimization at scale requires more than autoscaling. Cast AI for Karpenter is generally available and works without changes to your existing NodePool or EC2NodeClass configurations. It adds ML-based Spot interruption prediction and automated rightsizing on top of your current Karpenter setup:

  • ML-based Spot interruption prediction: Cast AI’s model predicts interruptions before the two-minute EC2 warning arrives, enabling proactive migration with up to 94% reduction in interruptions. This is a material improvement over reactive SQS-based handling alone.
  • Container Live Migration: Generally available on AWS since November 2024,Container Live Migration moves stateful workloads between nodes with zero downtime. This makes Spot viable for workloads that were previously on-demand only because of statefulness concerns.
  • Rightsizing: Adjusts pod resource requests based on actual consumption, not initial estimates. Over-provisioned requests cause Karpenter to launch larger nodes than workloads actually need. Fixing that at the pod level reduces your effective cost before Karpenter even selects an instance type.
  • Customer results: Akamai achieved 40-70% cloud cost savings. Yotpo reduced cloud costs by 40%. Both results combine Karpenter’s provisioning speed with Cast AI’s optimization layer.

Teams that use Karpenter to manage EKS capacity can add Cast AI via a read-write agent with no controller changes. There are no NodePool or EC2NodeClass changes required to get started. Request a demo to see the efficiency and cost impact on your cluster using your actual workload data.

Conclusion #

Karpenter’s defaults are not production-ready. Following best practices means making deliberate choices: isolating the controller, defining NodePool boundaries, wiring SQS before running Spot workloads, pinning AMIs, and configuring disruption budgets around your actual traffic patterns. Each practice in this guide addresses a failure mode that occurs in real clusters under real load.

The v1 API brings important changes: expireAfter moved to spec.template.spec, WhenUnderutilized became WhenEmptyOrUnderutilized, and amiSelectorTerms is now required. Update your manifests before upgrading. The investment is worth it: the v1 API is stable and the disruption control model is meaningfully better than its predecessors.

If you want to go further, whether that means predicting Spot interruptions before they happen, rightsizing pods automatically, or running stateful workloads on Spot without downtime, talk to the Cast AI team. Bring your cluster metrics and we will show you what the optimization layer looks like on your actual workload.

Frequently Asked Questions #

What are Karpenter best practices for production?

The core Karpenter best practices for production are: run the controller on dedicated nodes it cannot disrupt; use mutually exclusive NodePools with taints for workload isolation; set resource limits on every NodePool; wire the SQS interruption queue before using Spot; pin AMIs with versioned aliases instead of @latest; configure disruption budgets to protect peak traffic windows; set expireAfter in spec.template.spec (not spec.disruption); and monitor with stable Prometheus metrics. All examples should use the v1 stable API with apiVersion: karpenter.sh/v1 for NodePool and apiVersion: karpenter.k8s.aws/v1 for EC2NodeClass.

How is Karpenter different from Cluster Autoscaler?

The kubernetes cluster autoscaler scales pre-defined node groups based on pending pods. Karpenter provisions individual nodes directly from Amazon EC2 based on pod scheduling requirements, without requiring managed node groups to be defined in advance. It typically provisions nodes in under 60 seconds versus several minutes for the kubernetes cluster autoscaler. Karpenter also supports fine-grained instance-type selection, disruption budgets, and native Spot interruption handling via SQS. For a detailed comparison, see our Karpenter vs Cluster Autoscaler guide.

How do I enable Spot interruption handling in Karpenter?

To enable interruption handling, create an SQS queue and configure five EventBridge rules to forward EC2 Spot Instance Interruption Warnings, Rebalance Recommendations, State-change Notifications, AWS Health Events, and Capacity Reservation Interruption Warnings to it. Then pass the queue name to the Karpenter controller via –interruption-queue or the INTERRUPTION_QUEUE environment variable. Do not run the Node Termination Handler alongside Karpenter for interruption handling, as they conflict. The Karpenter IAM role needs sqs:ReceiveMessage, sqs:DeleteMessage, and sqs:GetQueueUrl permissions on the queue.

How do I pin AMIs in Karpenter v1?

In Karpenter v1, set amiSelectorTerms in your EC2NodeClass spec. For production, use a versioned alias such as alias: al2023@v20240219. For dev or staging, alias: al2023@latest is acceptable. The amiSelectorTerms field is required in v1; omitting it causes a validation error. Drift detection is stable and on by default in v1, so Karpenter will automatically replace nodes when you update the pinned alias version. Do not add –feature-gates Drift=true, as that flag was removed in v1.

What disruption budgets should I set in Karpenter?

If you define no budget, Karpenter defaults to nodes: 10%, meaning up to 10% of managed nodes can be voluntarily disrupted simultaneously at any time. For production, add a scheduled budget that sets nodes: “0” during business hours to freeze voluntary disruptions during peak traffic. Use WhenEmptyOrUnderutilized as the consolidation policy (renamed from WhenUnderutilized in v1). Set consolidateAfter to at least 1 minute to prevent thrashing on transient load dips, and longer (5-10 minutes) for stateful workloads. Monitor karpenter_voluntary_disruption_decisions_total to verify that budgets are working as configured.

What Prometheus metrics should I monitor with Karpenter?

Use only stable metrics for production alerting. The stable metrics in Karpenter v1 are: karpenter_pods_startup_duration_seconds (pod creation to running; alert on p99 against your SLO), karpenter_voluntary_disruption_decisions_total (disruption counts by reason), karpenter_nodeclaims_terminated_total (all NodeClaim terminations by nodepool, capacity type, and zone; alert on high rates), and karpenter_nodeclaims_created_total (NodeClaims provisioned). Alpha metrics useful for observability but subject to change include karpenter_nodepools_usage and karpenter_nodepools_limit. The metrics endpoint is karpenter.kube-system.svc.cluster.local:8080/metrics. Note that karpenter_pods_provisioning_startup_duration_seconds is an Alpha metric and should not be used for production alerting.

Does Karpenter work with Amazon EKS Auto Mode?

Amazon EKS Auto Mode uses Karpenter internally to manage node provisioning. When EKS Auto Mode is enabled, AWS manages the Karpenter controller and its underlying NodePool configurations. You can still apply many of the practices in this guide, such as workload annotations, pod scheduling constraints, and Prometheus monitoring, but you have less direct control over NodePool and EC2NodeClass configurations compared to a self-managed Karpenter install. Check the EKS Auto Mode documentation for the current set of configurable parameters.

What does Cast AI add to Karpenter?

Cast AI extends Karpenter with capabilities outside its core scope: ML-based Spot interruption prediction (up to 94% fewer interruptions), Container Live Migration for zero-downtime movement of stateful workloads to Spot (GA on AWS, November 2024), and automated pod rightsizing based on actual resource consumption. Cast AI for Karpenter is generally available and requires no changes to existing NodePool or EC2NodeClass configurations. Customers including Akamai (40-70% cost savings) and Yotpo (40% cost reduction) use it alongside Karpenter for production cluster optimization.

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @cast ai 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/karpenter-best-pract…] indexed:0 read:19min 2026-09-04 ·