Skip to content
Techsense Developers
TrustLet's Talk
Insights
Cloud & Infrastructure8 min readAug 31, 2026

How Does Autoscaling in Kubernetes on AWS Reduce Cloud Costs?

Kubernetes autoscaling on AWS reduces cloud costs by matching the compute you pay for to the load you actually serve. Instead of provisioning for peak traffic around the clock, autoscaling adds…

Kubernetes autoscaling on AWS reduces cloud costs by matching the compute you pay for to the load you actually serve. Instead of provisioning for peak traffic around the clock, autoscaling adds capacity when demand rises and removes it when demand falls. On AWS EKS, this happens at two layers: the Horizontal Pod Autoscaler (HPA) scales your application pods, and the Cluster Autoscaler (or Karpenter) scales the underlying EC2 nodes. When both are tuned correctly, you stop paying for idle nodes and over-provisioned pods, which is where most Kubernetes bills quietly leak money.

Below, I will walk through how each layer works, where the savings come from, and the practical configuration and pitfalls I see most often in production.

Why Static Provisioning Wastes Money

Most cost problems in Kubernetes trace back to a simple habit: teams size clusters for the worst case and leave them there. If your traffic peaks at 9 a.m. but your fleet is sized for 9 a.m. all day, you are paying for capacity you use for maybe two hours.

The waste compounds in a few ways:

  • Idle nodes. EC2 instances bill per second while running, whether or not pods are scheduled on them.
  • Over-requested pods. Kubernetes schedules based on resource requests, not actual usage. If a pod requests 2 vCPU but uses 0.3, the scheduler reserves 2 vCPU worth of node capacity that nothing else can use.
  • Fragmentation. Poor bin-packing leaves nodes 40 percent full but unable to accept new pods that need contiguous capacity.

Autoscaling attacks all three. The goal is not just "scale up when busy" but "scale down aggressively when idle," because the down-scaling is where the savings actually land.

The Two Layers of Kubernetes Autoscaling on AWS

To reduce costs with Kubernetes autoscaling on AWS, you need to understand that pod-level and node-level scaling solve different problems and must work together.

Horizontal Pod Autoscaler (HPA)

The HPA changes the number of pod replicas in a Deployment or StatefulSet based on observed metrics, most commonly CPU or memory utilization, though custom and external metrics are supported through the Kubernetes metrics API.

A basic HPA looks like this:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: checkout-api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: checkout-api
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 65

This tells Kubernetes to keep average CPU near 65 percent across replicas, scaling between 2 and 20 pods. When traffic drops, HPA removes replicas, which frees node capacity. That freed capacity is the precondition for node-level savings.

For metrics beyond CPU and memory, such as requests per second or queue depth, you attach a metrics adapter (for example, the Prometheus Adapter or KEDA). Scaling on a business-relevant signal like queue depth is usually far more cost-effective than scaling on CPU, because it tracks real work rather than a proxy.

Cluster Autoscaler and Karpenter

HPA alone does not save money. If you remove pods but keep the nodes, your bill is unchanged. That is the job of the node-scaling layer.

Cluster Autoscaler watches for pods that cannot be scheduled (pending due to insufficient resources) and adds nodes to an EC2 Auto Scaling Group to fit them. Conversely, when nodes sit under-utilized and their pods can be rescheduled elsewhere, it drains and terminates them.

Karpenter, an open-source project from AWS, is the more modern approach. Rather than working through fixed Auto Scaling Groups, it provisions right-sized EC2 instances directly, choosing instance types that best fit pending pods. This tighter bin-packing tends to cut cost further, and it consolidates workloads onto fewer nodes over time.

A minimal Karpenter provisioner (NodePool in current versions) might look like this:

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 30s
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot", "on-demand"]
        - key: node.kubernetes.io/instance-type
          operator: In
          values: ["m5.large", "m5.xlarge", "c5.large", "c5.xlarge"]

The consolidationPolicy setting is the direct lever on AWS EKS cost optimization: it tells Karpenter to actively repack workloads and terminate underused nodes.

Where the Savings Actually Come From

Autoscaling reduces cloud costs through several distinct mechanisms. It helps to name them so you can measure each one.

  1. Eliminating idle capacity. Scaling down at off-peak hours is the largest single win for most teams. A cluster that runs at 30 percent average utilization has roughly two-thirds of its spend available to recover.

  2. Better bin-packing. Consolidation moves pods onto fewer, well-utilized nodes and terminates the rest. Karpenter's consolidation and the Cluster Autoscaler's scale-down both do this.

  3. Using Spot Instances safely. Autoscaling makes Spot practical. Because the system can react to interruptions by launching replacement capacity, you can run fault-tolerant workloads on Spot at a substantial discount versus On-Demand. Reserve On-Demand or a small baseline for workloads that cannot tolerate interruption.

  4. Right-sizing instance selection. Karpenter picks the cheapest instance type that satisfies pod requirements, rather than forcing everything into one instance family.

  5. Reducing human error. Manual capacity planning tends to over-provision "to be safe." Automated scaling removes that padding.

Practical Configuration That Keeps Costs Down

I have seen autoscaling configured in ways that increase cost, usually because the down-scaling side was neglected. A few rules keep the savings real.

Set accurate resource requests

The scheduler reserves capacity based on requests. If they are inflated, no amount of autoscaling helps. Use the Vertical Pod Autoscaler (VPA) in recommendation mode, or analyze actual usage, then set requests close to real consumption plus a modest buffer.

resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    cpu: "1"
    memory: "512Mi"

Tune scale-down behavior

Cluster Autoscaler will not remove a node if it hosts pods that cannot be evicted. Common blockers include pods without controllers, pods using local storage, and restrictive PodDisruptionBudgets. Audit these, and set a reasonable scale-down-unneeded-time so nodes do not linger.

Protect availability with PodDisruptionBudgets

Aggressive scale-down can hurt availability if you let it drain too much at once. A PDB caps how many pods of a service can be unavailable during voluntary disruptions, which keeps consolidation from taking your service down.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: checkout-api
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: checkout-api

Avoid flapping

If HPA and node scaling react too fast, you get thrash: nodes launch and terminate repeatedly, which wastes money and destabilizes workloads. Use HPA stabilization windows and sensible cooldowns so scaling responds to trends, not noise.

Getting all of this working together is exactly the kind of hardening we cover in our cloud and infrastructure capabilities, where the difference between "autoscaling turned on" and "autoscaling that reliably saves money" comes down to these details.

Measuring the Result

You cannot claim savings you do not measure. Track:

  • Cluster utilization (requested vs. allocatable CPU/memory) over time.
  • Cost per node-hour and the Spot-to-On-Demand ratio, via AWS Cost Explorer and Kubecost or OpenCost.
  • Scale event frequency to catch flapping.

Tie these back to workload-specific patterns. A retail platform with predictable daily peaks scales differently from a data pipeline with bursty batch jobs, and we have seen those patterns play out across the industries we work with. The autoscaling strategy should follow the traffic shape, not a template.

A Sensible Rollout Order

  1. Deploy the metrics server and set accurate resource requests.
  2. Add HPA to stateless services with clear scaling signals.
  3. Add Cluster Autoscaler or Karpenter with conservative consolidation.
  4. Introduce Spot capacity for fault-tolerant workloads.
  5. Add PodDisruptionBudgets and tune stabilization windows.
  6. Measure, then tighten utilization targets as you gain confidence.

Done in that order, Kubernetes autoscaling on AWS moves you from paying for peak capacity all the time to paying for the work you actually do, without sacrificing the availability your users expect.

FAQ

What is the difference between the Horizontal Pod Autoscaler and the Cluster Autoscaler?

The Horizontal Pod Autoscaler changes the number of pod replicas based on metrics like CPU utilization. The Cluster Autoscaler (or Karpenter) changes the number of EC2 nodes to fit those pods. HPA frees up node capacity by removing pods; the node autoscaler converts that freed capacity into actual savings by terminating unneeded nodes. You typically need both.

Does autoscaling work with Spot Instances on EKS?

Yes, and it is one of the biggest cost levers available. Because autoscaling can quickly replace interrupted capacity, you can safely run fault-tolerant, stateless workloads on Spot Instances at a significant discount versus On-Demand. Keep a baseline of On-Demand capacity for workloads that cannot tolerate interruption.

Why did my costs go up after enabling autoscaling?

Usually because the scale-down path is blocked or the resource requests are inflated. Pods without PodDisruptionBudgets set correctly, pods using local storage, or overly high CPU/memory requests prevent nodes from being consolidated and terminated. Autoscaling only saves money when nodes can actually be removed during low demand.

Should I use Cluster Autoscaler or Karpenter?

Both are valid. Cluster Autoscaler works through fixed EC2 Auto Scaling Groups and is well established. Karpenter provisions right-sized instances directly and consolidates workloads more aggressively, which often yields better bin-packing and lower cost. Many teams moving to newer EKS setups choose Karpenter for the flexibility.

How do I measure the savings from Kubernetes autoscaling?

Track cluster utilization (requested versus allocatable resources), cost per node-hour, and the Spot-to-On-Demand ratio using AWS Cost Explorer alongside a tool like Kubecost or OpenCost. Watch scale-event frequency to ensure you are not flapping. Compare utilization before and after tuning to quantify the recovered spend.

Production-grade cloud, software, and engineering teams for scaling companies.