KubernetesLXXXIII · Vertical Pod Autoscaling ConceptsVertical Pod Autoscaler
VPA limitations — the boundaries of vertical scaling
What you'll learn
- Identify the VPA limitations
- Plan around the pod restart requirement
- Configure the VPA for production
- Recognize the VPA's boundary cases
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 VPA has a set of limitations that production operators must plan around. The pod restart requirement, the interaction with HPA, the resource limits, and the storage of usage history are the boundary cases. This lesson walks the limitations and the production patterns that work around them.
The pod restart requirement
The VPA’s eviction-then-recreate pattern requires a pod restart:
flowchart LR
A[Pod with old requests] --> B[VPA updater evicts]
B --> C[New pod created]
C --> D[Pod with new requests]
The pod restart is required because the resource requests of a running pod cannot be changed. The pod must be evicted and recreated.
The impact on stateful workloads
The pod restart is a problem for stateful workloads:
Postgres pod evicted by VPA
Postgres pod restarted
Database connection pool reset
Application reconnect
The restart is disruptive. The mitigation is to use VPA
in Off mode or to use the Initial mode:
updatePolicy:
updateMode: "Initial"
The Initial mode sets the requests on pod creation only; no eviction is required.
The HPA conflict
The VPA and HPA conflict on the same metric:
# VPA on CPU
controlledResources: ["cpu"]
# HPA on CPU
metrics:
- type: Resource
resource:
name: cpu
The two autoscalers fight each other. The VPA changes the request, which changes the CPU utilization, which triggers the HPA, which may trigger the VPA again.
The mitigation is to use different metrics or to use either VPA or HPA, not both.
The resource limits
The VPA’s recommendations are bounded by
minAllowed and maxAllowed. The bounds are the
container’s resource limits:
resourcePolicy:
containerPolicies:
- containerName: nginx
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 4Gi
The VPA cannot recommend a request outside the bounds.
flowchart LR
A[Recommendation] --> B{Bounds?}
B -->|Inside| C[Recommended]
B -->|Outside| D[Bound to min/max]
The history storage
The VPA’s recommendation is based on historical data. The recommender stores the historical data in memory:
The recommender stores:
- 8 days of CPU usage samples
- 8 days of memory usage samples
- Per-pod, per-container
The memory storage is per-pod; the recommender needs sufficient memory to store the history.
The recommender uses the metrics server as the source:
spec:
resourcePolicy:
containerPolicies:
- containerName: nginx
historicalDataWindow: 8d
The history window is configurable.
The cold-start
The VPA’s recommendation is cold-start:
Pod 1 day old: insufficient data; recommendation is at minAllowed
Pod 8 days old: full data; recommendation is at the 90th percentile
The cold-start is the first 8 days. The recommendation is conservative; the VPA trusts the existing requests until the history is sufficient.
The non-CPU-bound workloads
The VPA is most effective for CPU-bound workloads. For memory-bound workloads, the VPA may not be as effective:
CPU-bound: VPA recommends higher CPU; the workload benefits
Memory-bound: VPA recommends higher memory; the workload benefits
I/O-bound: VPA's recommendations are less relevant; the bottleneck is not CPU/memory
The VPA is for CPU and memory; for I/O-bound workloads, the bottleneck is elsewhere.
The update mode boundaries
The three update modes have different boundaries:
Off: recommendations only; no pod updates.Initial: sets on pod creation; running pods are not updated.Auto: evicts and recreates pods.
The choice depends on the workload:
| Workload | Recommended mode |
|---|---|
| Stateful | Off or Initial |
| Stateless | Auto |
| Critical | Off or Initial |
The storage of recommendations
The VPA’s recommendations are stored in the VPA object’s status:
kubectl describe vpa nginx-vpa
Status:
Recommendation:
Container Recommendations:
Container Name: nginx
Target:
Cpu: 100m
Memory: 200Mi
The recommendations are readable via the VPA API.
The cross-course references
- The HPA course (Part LXXXII) covers the horizontal alternative.
- The Capacity Planning course (Part LXXXIV) covers the resource planning.
- The Observability course covers VPA monitoring.
Quiz
Knowledge check · 4 questions
Q1. What is the main VPA limitation for stateful workloads?
Q2. The VPA's `Initial` mode sets the requests on pod creation only and does not update running pods.
Q3. Walk the VPA configuration for a stateful workload that cannot tolerate pod restarts.
Postgres StatefulSet with 3 replicas. The team is configuring the VPA but the workload cannot tolerate pod restarts. The VPA recommendations are needed for right-sizing.
Q4. What is the VPA cold-start, and how is it handled?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Choose the updateMode per workload. Off, Initial, or Auto.
- Plan for pod restarts. Stateful workloads need careful planning.
- Use different metrics for VPA and HPA. Avoid mixing on the same metric.
- Set minAllowed and maxAllowed. Bound the recommendations.
- Allow 8 days for history. The cold-start is the first 8 days.
- Document the VPA configuration. The mode, the bounds, the rationale.
The VPA limitations are the boundary cases. Operating it well is choosing the right update mode, bounding the recommendations, and planning for the pod restarts.