Right-Sizing & Spot Strategy for Cost

Set requests honestly, diversify Spot across many pools, and protect the few pods that must never be interrupted.

Most EKS bills are bloated for two boring reasons: requests set far above real usage, and everything running on on-demand. Fix those two and you routinely cut compute cost by half.

Right-size with real data

  • The scheduler packs nodes by requests, not actual use. A pod requesting 2 vCPU but using 0.2 wastes 90% of the slot it reserves.
  • Use the Vertical Pod Autoscaler in recommendation mode (or metrics from Container Insights / Prometheus) to see what pods really consume, then set requests close to the p95.
  • Set requests to reserve headroom; keep CPU limits loose (or unset) so bursts aren't throttled, but always set memory limits to prevent noisy-neighbor OOM.

Spot the right way

  • Diversify. Spread across many instance types and AZs so one interruption event can't drain your whole fleet. This is where Karpenter or a mixed-instances ASG shines.
  • Handle interruptions. Spot gives a 2-minute warning; make sure pods have PodDisruptionBudgets and graceful shutdown so they drain cleanly.
  • Keep an on-demand floor. Run stateful or single-replica critical workloads on on-demand (or a small guaranteed group) and let stateless, replicated work ride Spot.

Split by lifecycle

Label nodes by lifecycle and use nodeSelector/affinity so batch and stateless tiers prefer Spot, while databases and controllers stay on-demand.

Example

Example Β· yaml
# A stateless deployment that prefers Spot but tolerates its taint
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 6
  template:
    spec:
      nodeSelector:
        karpenter.sh/capacity-type: spot
      tolerations:
        - key: karpenter.sh/capacity-type
          operator: Equal
          value: spot
          effect: NoSchedule
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels: { app: web }
      containers:
        - name: web
          image: public.ecr.aws/nginx/nginx:1.27
          resources:
            requests: { cpu: "200m", memory: "256Mi" }
            limits: { memory: "256Mi" }

When to use it

  • A cost team runs the Vertical Pod Autoscaler in recommendation mode to discover that half their pods over-request CPU by 4x and corrects requests to reduce wasted Spot node capacity.
  • A platform team configures node groups with 10 Spot instance types across multiple families so Spot interruptions in one pool are absorbed by available capacity in another.
  • A DevOps engineer uses AWS Spot Interruption Notices via IMDS to gracefully drain batch pods before the 2-minute reclaim window expires.

More examples

Spot node group with instance diversification

Defines a Spot managed node group with five instance types so Spot capacity shortfalls in one type automatically fall back to alternatives.

Example Β· yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: prod
  region: us-east-1
managedNodeGroups:
- name: spot-workers
  instanceTypes:
  - m5.xlarge
  - m5a.xlarge
  - m4.xlarge
  - m5d.xlarge
  - m5n.xlarge
  spot: true
  minSize: 0
  maxSize: 30

Set honest resource requests

Resource requests set to actual measured usage rather than guesses, enabling tighter bin-packing on Spot nodes and more accurate autoscaler decisions.

Example Β· yaml
containers:
- name: api
  resources:
    requests:
      cpu: "200m"   # actual P95 usage from VPA recommendations
      memory: "256Mi"
    limits:
      cpu: "800m"   # burst headroom
      memory: "512Mi"

Handle Spot interruption gracefully

Sets a 90-second grace period and preStop hook so in-flight requests complete before the pod is terminated on Spot interruption.

Example Β· yaml
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      terminationGracePeriodSeconds: 90
      containers:
      - name: worker
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 10"]

Discussion

  • Be the first to comment on this lesson.
Right-Sizing & Spot Strategy for Cost β€” Amazon EKS | SoundsCode