KubernetesLXXXII · Horizontal Pod AutoscalerHorizontal Pod Autoscaler
Behavior block — stabilization and scaling policies
What you'll learn
- Configure the HPA behavior block
- Set the stabilization window
- Configure the scaling policies
- Avoid thrashing and flapping
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
The HPA behavior block controls the scaling behavior: the stabilization window prevents flapping, and the scaling policies limit the rate of scale-up and scale-down. This lesson walks the behavior block, the stabilization window, and the scaling policies.
The behavior block
The behavior block is part of the HPA configuration:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max
The stabilization window
The stabilization window is the time the HPA looks back to determine the desired replica count:
scaleDown:
stabilizationWindowSeconds: 300
The default for scale-down is 300 seconds (5 minutes). The HPA looks at the last 5 minutes of metrics; the highest desired replica count is selected.
gantt
title Stabilization window (scale-down)
dateFormat YYYY-MM-DD
section History
Last 5 minutes of metrics :done, 2026-08-16, 5m
section Decision
Take the highest desired replica count :crit, 2026-08-16, 5m
The stabilization window prevents a brief spike from causing a scale-down.
For scale-up, the default is 0 seconds (immediate). The HPA scales up immediately when the metric exceeds the target.
The default behaviour
An HPA with no behavior block behaves as if it carried
this one:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
Read it carefully, because it is not what most operators
assume. The default asymmetry lives entirely in the
stabilisation window: scale-up acts on the current
recommendation, scale-down waits 300 seconds and then
acts on the highest recommendation seen in that window.
The rate policies are the same in both directions —
100% of the current replicas per 15 seconds — with an
extra 4-Pods-per-15s policy and selectPolicy: Max on
the way up. Once the window expires, the default
scale-down can take the workload straight to
minReplicas in a single step.
The scaling policies
The scaling policies limit the rate of scale-up and scale-down:
scaleUp:
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max
The policies:
Percent: scale up by N% of current replicas per period.Pods: scale up by N pods per period.selectPolicy: Max: the larger of the two policies is used.
The example:
- 100% of current replicas per 30s (e.g., 5 → 10 in 30s).
- 4 pods per 30s.
The Max selectPolicy means the HPA uses the larger
limit. The HPA can double the replicas in 30 seconds.
Note the periodSeconds: the example uses 30, while the
default is 15.
Tuning the scale-down policies
The default scale-down policy is not conservative — it allows the whole replica set to be removed in one 15 second period. A workload that must shed capacity gradually needs the policy written out:
scaleDown:
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 1
periodSeconds: 60
selectPolicy: Min
The example:
- 10% of current replicas per 60s (e.g., 10 → 9 in 60s).
- 1 pod per 60s.
The Min selectPolicy means the HPA uses the smaller
limit. At 10 replicas both policies work out to 1 Pod,
so this HPA scales down by one Pod per minute.
The asymmetry
The asymmetry that ships with the HPA is a matter of timing, not rate:
flowchart LR
A[Default scale-up] --> B[No stabilisation window]
B --> C["100% per 15s, or 4 Pods per 15s, Max"]
D[Default scale-down] --> E[300s stabilisation window]
E --> F["Then 100% per 15s"]
G[Tuned scale-down] --> H[300s window]
H --> I["Then 10% per 60s, or 1 Pod per 60s, Min"]
Scale-up reacts to demand immediately. Scale-down waits five minutes and takes the highest recommendation from that window, which is what prevents a transient dip from shrinking the workload. What the default does not do is make the descent gradual — that is the tuning shown above.
The stabilization window defaults
The default stabilization window:
| Direction | Window |
|---|---|
| scaleUp | 0s (immediate) |
| scaleDown | 300s (5 minutes) |
The asymmetry is the default. The operator can override the windows.
The flapping
Flapping is the rapid scale-up and scale-down:
T+0: CPU 80% → scale up to 5
T+30s: CPU 50% → scale down to 4
T+60s: CPU 80% → scale up to 5
T+90s: CPU 50% → scale down to 4
The flapping is caused by short-term oscillations. The stabilization window prevents flapping:
T+0: CPU 80% → desired replicas 5
T+30s: CPU 50% → desired replicas 4
T+60s: CPU 80% → desired replicas 5
Without stabilization: replicas oscillate 4-5
With stabilization (5m): HPA uses the max desired replicas (5)
The stabilization window looks at the history; the highest desired replica count is selected.
A tuned behavior block
Putting the tuning together — the defaults kept for the windows, an explicit conservative descent added:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 1
periodSeconds: 60
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max
The behavior is per-HPA. Different workloads may have different behaviors.
Cross-course references
- The Helm course covers chart values for HPA behavior.
- The Observability course covers HPA metrics.
- The KEDA course covers advanced scaling behaviors.
Quiz
Knowledge check · 4 questions
Q1. What is the default stabilizationWindowSeconds for scale-down?
Q2. The HPA's default scaling behavior is asymmetric: scale-up is fast, scale-down is slow.
Q3. Walk the configuration of the HPA behavior block for a production workload.
Deployment nginx. The workload is critical (e.g., payment processing). The team is configuring the HPA to scale conservatively (fast scale-up, slow scale-down).
Q4. What is HPA flapping, and how is it prevented?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Configure the behavior block. The default delays a scale-down by five minutes but does not slow it down; tune for the workload.
- Set the scale-up policies. Aggressive (e.g., 100% per 30s).
- Set the scale-down policies. Conservative (e.g., 1 pod per 60s).
- Set the stabilization window. 5 minutes for scale-down.
- Test the behavior. Generate load; verify the scaling.
- Document the behavior. The policies, the window, the rationale.
The behavior block is the HPA’s production tuning. Operating it well is configuring the policies and the window per workload.