Horizontal Pod Autoscaler can match replica capacity to demand, but it is not a substitute for resource sizing or load testing. An HPA makes decisions from metrics, and weak metrics or inaccurate requests produce unstable scaling.

This guide explains the control loop, autoscaling/v2 configuration, CPU utilization math, custom metrics, stabilization behavior and the cluster-capacity checks required before trusting autoscaling in production.

What you will learn

  • HPA changes desired replicas on scalable workloads such as Deployments and StatefulSets.
  • CPU utilization targets are percentages of container requests, making requests essential inputs.
  • autoscaling/v2 supports multiple metrics and behavior controls.
  • Scaling Pods cannot help when nodes lack capacity, dependencies are saturated or startup is too slow.

How the control loop works

The HPA controller periodically reads metrics for Pods selected by the target workload. It compares current and desired metric values, calculates a replica recommendation and updates the scale subresource.

It is an intermittent feedback loop, not instant reaction. Metric collection delay, sync periods, Pod startup and readiness all affect response time. Capacity planning must cover demand while new replicas become useful.

CPU targets depend on requests

For resource utilization, the controller compares measured CPU with the corresponding CPU request. If requests are missing for relevant containers, the controller may be unable to calculate utilization correctly for those Pods.

A target of 60 percent does not mean 60 percent of a node or CPU limit. It means average usage relative to requests. Set requests from measurements before tuning the target.

A production-shaped autoscaling/v2 example

Set a minimum that survives normal failures and a maximum supported by dependencies and budget. Behavior policies can limit change velocity and stabilization windows can reduce oscillation.

The example uses CPU as an accessible starting point. Request rate, queue depth or concurrency may represent demand better for many services, provided the metric pipeline is reliable.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 3
  maxReplicas: 30
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300

Choose a metric tied to demand

CPU works when it rises predictably with work. It is weak for I/O-bound services, consumers waiting on queues, or bottlenecks hidden in a downstream database. Consider requests per second, active work, queue depth or latency-informed signals.

Custom and external metrics increase power and operational dependency. Define units, freshness, missing-data behavior and ownership. Test what happens when the metrics adapter is unavailable.

Prevent flapping and unsafe scale-down

Short spikes can create unnecessary replicas, while aggressive scale-down can remove warm capacity and cause repeated oscillation. Configure stabilization and change policies based on traffic shape, startup time and cost.

Readiness matters because starting Pods may have unusual CPU behavior. A startup probe can keep initialization separate, while readiness ensures only prepared replicas receive traffic. Preserve enough minimum capacity for sudden demand and maintenance.

Troubleshoot HPA systematically

Describe the HPA and inspect current metrics, conditions and events. Verify that Metrics API data exists, the scale target name is correct, Pod labels match, requests are defined and the maximum has not been reached.

If desired replicas rise but Pods stay Pending, the bottleneck is cluster capacity or placement. If replicas run but latency persists, inspect dependencies, concurrency, throttling and whether the chosen metric represents user demand.

kubectl describe hpa api -n production
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/production/pods
kubectl get pods -n production -l app=api

Production checklist

  • Set measured requests before using utilization targets.
  • Choose metrics that correlate with demand and service health.
  • Define safe minimum and dependency-tested maximum replicas.
  • Configure stabilization and rate policies from traffic behavior.
  • Ensure node capacity can schedule the maximum useful scale.
  • Alert on missing metrics, maxed HPA and Pending replicas.

Frequently asked questions

Does HPA require metrics-server?

CPU and memory resource metrics generally come through metrics.k8s.io, commonly provided by metrics-server. Custom metrics need an appropriate adapter or provider.

Can HPA scale a DaemonSet?

No. HPA targets scalable resources exposing a scale subresource; DaemonSets are not horizontally scaled this way.

Why does HPA show unknown utilization?

Common causes include missing resource requests, unavailable metrics, newly started or unready Pods, and selector or adapter problems.

Continue learning Kubernetes

Official Kubernetes references