KubernetesLXXXIII · Vertical Pod Autoscaling ConceptsVertical Pod Autoscaler
VPA vs HPA — when to use which
What you'll learn
- Choose between VPA and HPA per workload
- Identify the workloads that benefit from each
- Plan the VPA-only, HPA-only, and hybrid patterns
- Avoid the anti-patterns
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 vs HPA decision is per workload. VPA scales resources; HPA scales pods. Some workloads benefit from VPA; others benefit from HPA. This lesson walks the decision criteria, the workloads that benefit from each, and the production patterns.
The decision framework
flowchart LR
A[Workload] --> B{Stateful?}
B -->|yes| C[VPA]
B -->|no| D{Replicas needed?}
D -->|yes| E[HPA]
D -->|no| F[Static]
The decision is based on the workload’s characteristics.
VPA workloads
VPA is suitable for:
- Stateful workloads. Databases, queues, caches that have a fixed replica count and benefit from right-sizing.
- Monolithic workloads. Legacy applications that cannot easily scale horizontally.
- Resource-sensitive workloads. Workloads that have unique resource profiles that benefit from right-sizing.
flowchart LR
A[VPA workloads] --> B[Stateful]
A --> C[Monolithic]
A --> D[Resource-sensitive]
VPA is the right choice when the workload has a fixed replica count and the resources per pod are the scaling target.
HPA workloads
HPA is suitable for:
- Stateless workloads. Web services, microservices that can scale horizontally.
- Component workloads. APIs, front-ends that can handle traffic spikes by adding replicas.
- Burst-aware workloads. Workloads that have variable load and benefit from horizontal scaling.
flowchart LR
A[HPA workloads] --> B[Stateless]
A --> C[Component]
A --> D[Burst-aware]
HPA is the right choice when the workload can scale horizontally and the number of replicas is the scaling target.
The hybrid pattern
The hybrid pattern uses VPA and HPA on different metrics:
# VPA on memory
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
spec:
resourcePolicy:
containerPolicies:
- containerName: nginx
minAllowed:
memory: 128Mi
maxAllowed:
memory: 4Gi
controlledResources: ["memory"]
---
# HPA on CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
The VPA controls memory; the HPA controls CPU. The two do not conflict.
The VPA-only pattern
The VPA-only pattern is for workloads that cannot scale horizontally:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: db-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: StatefulSet
name: db
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: postgres
minAllowed:
cpu: 1
memory: 4Gi
maxAllowed:
cpu: 16
memory: 64Gi
The VPA right-sizes the database. The StatefulSet has a fixed replica count (e.g., 3); the VPA adjusts the resources per pod.
The HPA-only pattern
The HPA-only pattern is for stateless workloads:
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
The HPA scales the replicas. The VPA is not used.
The static pattern
The static pattern is for workloads that are sized manually:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 5
template:
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1
memory: 2Gi
The workload is sized manually. The replica count and the resources are fixed.
The anti-pattern: mixing VPA and HPA on the same metric
# VPA on CPU
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
spec:
resourcePolicy:
containerPolicies:
- containerName: nginx
controlledResources: ["cpu"]
---
# HPA on CPU
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
metrics:
- type: Resource
resource:
name: cpu
The VPA may change the resource request, which changes the CPU utilization, which triggers the HPA, which may trigger the VPA again. The feedback loop is unstable.
Cross-course references
- The HPA course (Part LXXXII) covers the horizontal alternative.
- The Cluster Autoscaler course (Part LXXXI) covers the cluster-level scaling.
- The Capacity Planning course (Part LXXXIV) covers the resource planning.
Quiz
Knowledge check · 4 questions
Q1. Which workload is most suitable for VPA?
Q2. VPA on memory and HPA on CPU is a stable hybrid pattern.
Q3. Walk the VPA vs HPA decision for a Postgres database and a stateless web service.
Postgres StatefulSet with 3 replicas. Nginx Deployment with 5 replicas. The team is choosing between VPA and HPA for each workload.
Q4. Why is mixing VPA and HPA on the same metric an anti-pattern?
Passing score: 75%. Answers are checked in this browser.
Production discipline
- Choose VPA or HPA per workload. Not both on the same metric.
- VPA: stateful, monolithic, resource-sensitive. HPA: stateless, component, burst-aware.
- Hybrid: VPA on memory, HPA on CPU. A stable pattern.
- Avoid mixing on the same metric. The feedback loop is unstable.
- Test the autoscaling strategy. Use load generation to verify the behavior.
- Document the decision. VPA or HPA, the rationale, the configuration.
The VPA vs HPA decision is per workload. Operating it well is choosing the right strategy, avoiding the anti-patterns, and documenting the decision.