Autoscaling with HPA

Autoscaling with HPA

The HorizontalPodAutoscaler changes replicas of a Deployment (or StatefulSet) based on metrics.

graph LR K[kubelets] --> MS[metrics-server] MS -->|metrics.k8s.io| HPA[HPA controller<br/>every 15 s] HPA -->|scale| D[Deployment] D --> P[Pods]
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: web }
  minReplicas: 1
  maxReplicas: 6
  metrics:
    - type: Resource
      resource:
        name: cpu
        target: { type: Utilization, averageUtilization: 50 }   # % of the REQUEST
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300    # default: wait 5 min before shrinking

desired = ceil(current replicas x current usage / target) Example: 2 Pods at 150 % CPU, target 50 % -> ceil(2 x 150 / 50) = 6.

Rules of thumb

  • Utilization is relative to requests - no request, no scaling (TARGETS <unknown>).
  • Do not set replicas in the manifest you apply - it fights the HPA.
  • Scale-up is fast, scale-down deliberately slow (flapping protection).

The wider family

ToolScales
HPAnumber of Pods (CPU, memory, custom metrics)
VPArequests/limits of Pods (addon)
KEDAPods on events - queue length, Kafka lag, cron; down to zero
Cluster Autoscaler / Karpenternumber of nodes (cloud)

References