Vertical Pod Autoscaler (VPA) Explained

Khimananda Oli 7 min read Virtualization
Vertical Pod Autoscaler (VPA) Explained

By Khimananda Oli | Last reviewed: August 2026

Over-provisioned pods waste cloud budget while under-provisioned ones cause OOM kills and latency spikes; the Vertical Pod Autoscaler (VPA) explained here solves this by automatically adjusting CPU and memory requests based on actual usage. Unlike horizontal scaling which adds replicas, VPA right-sizes individual containers to match their true resource profile. This guide covers the architecture, safe update modes, and production patterns I use daily to stabilize workloads and reduce spend.

VPA Architecture OverviewMetrics ServerCPU / Memory UsageHistorical SamplesVPA RecommenderAnalyzes MetricsGenerates RecommendationsK8s API ServerVPA CRD StatusPod Spec UpdatesAdmission ControllerMutates New Pods(Initial / Auto Mode)VPA UpdaterEvicts Outdated Pods(Auto Mode Only)Watches VPA Objects
Vertical Pod Autoscaler architecture: Recommender analyzes metrics, Admission Controller sets resources on creation, Updater evicts pods for re-sizing in Auto mode.

How does Vertical Pod Autoscaler (VPA) work in Kubernetes?

The Vertical Pod Autoscaler (VPA) explained through its three core components reveals why it behaves differently than HPA. The Recommender runs as a deployment that polls the Metrics Server every minute, building a histogram of CPU and memory usage over an 8-day rolling window. It calculates target values using percentile-based algorithms (default: 90th percentile for requests, 95th for limits) and writes recommendations to the VPA object’s status field. This separation means recommendations persist even if the Updater or Admission Controller fails.

The Admission Controller is a webhook that intercepts pod creation requests. When a new pod matches a VPA selector, it mutates the pod spec to inject recommended resources before the scheduler sees it. This is critical for Initial and Auto modes. Without it, pods launch with stale or missing resource specs. The Updater, meanwhile, watches existing pods against current recommendations. In Auto mode, it evicts pods whose actual resources deviate beyond a threshold (default: 10%), forcing recreation with updated values via the Admission Controller.

A common mistake is assuming VPA works like HPA. It does not scale replicas; it scales density per pod. This makes it ideal for singletons, batch jobs, or stateful sets where horizontal scaling is impossible or inefficient. However, eviction-based resizing causes brief downtime. For latency-sensitive services, always pair VPA with proper resource requests and limits baselines and use Off mode initially to validate recommendations before enabling automation.

What are the VPA update modes and when should you use each?

Choosing the right update mode determines whether VPA acts as an advisor or an actuator. Misconfiguration here is the #1 cause of production incidents involving VPA. Below is a decision framework grounded in real cluster operations.

  • Off: VPA computes recommendations but never applies them. Safe for all workloads. Use this for baseline assessment, compliance audits, or when integrating with GitOps tools like ArgoCD that manage manifests declaratively.
  • Initial: Resources are set only at pod creation. Existing pods are never evicted. Ideal for stateful applications (databases, message brokers) where restarts are costly but new instances should be right-sized.
  • Auto: Full lifecycle management. Applies resources on creation and evicts running pods when drift exceeds thresholds. Best for stateless, replicated deployments with graceful shutdown handling.
ModeApplies on CreateEvicts Running PodsDowntime RiskBest For
OffNoNoNoneAudits, GitOps, learning phase
InitialYesNoLow (only new pods)Databases, stateful sets, legacy apps
AutoYesYesModerate (eviction cycles)Stateless microservices, batch workers

In practice, I start every workload in Off mode for 7–14 days. This captures weekly cycles (e.g., Monday traffic spikes, weekend batch loads). Only after confirming recommendations align with SLOs do I switch to Initial or Auto. For teams using Horizontal Pod Autoscaler, remember: VPA and HPA can coexist safely only if HPA targets custom metrics or if VPA manages memory while HPA manages CPU. Never let both control the same resource dimension simultaneously.

How do you configure VPA safely for production workloads?

Safe VPA configuration requires explicit bounds, exclusion rules, and observability. Blindly applying defaults leads to thrashing or starved pods. Follow this checklist derived from SOC 2-compliant infrastructure reviews.

  1. Define min/max boundaries: Always set minAllowed and maxAllowed in your VPA spec. Unbounded VPAs can recommend 10m CPU during idle periods or 32Gi memory during outliers, causing scheduling failures or cost explosions.
  2. Exclude critical containers: Use containerPolicies to skip sidecars (envoy, vault-agent) or init containers. VPA should only manage application containers with predictable resource profiles.
  3. Tune update thresholds: Adjust updatePolicy.minReplicas (default: 2) to prevent evicting the last replica. Set resourcePolicy.controlledValues to RequestsOnly if limits are managed externally.
  4. Validate with Off mode first: Deploy VPA in Off mode and monitor vpa_status_recommendation metrics via Prometheus. Compare against actual usage dashboards before enabling automation.
<!-- vpa-production.yaml -->
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: api-server-vpa
  namespace: backend
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  updatePolicy:
    updateMode: "Auto"
    minReplicas: 3
  resourcePolicy:
    containerPolicies:
    - containerName: api-container
      controlledValues: RequestsAndLimits
      minAllowed:
        cpu: 100m
        memory: 256Mi
      maxAllowed:
        cpu: 2000m
        memory: 4Gi
    - containerName: envoy-sidecar
      mode: "Off"

This configuration ensures the API container stays within safe bounds while ignoring the Envoy sidecar. The minReplicas: 3 guard prevents total service disruption during eviction waves. Pair this with meaningful SLIs/SLOs to detect if VPA-induced restarts violate error budgets. If they do, revert to Initial mode or widen the tolerance band.

VPA Update Mode Decision FlowStart AssessmentIs workload stateful or latency-critical?YESNOUse Initial ModeUse Auto ModeSet minReplicas ≥ 2Monitor eviction rate & SLOsAlways Start in Off Mode First
Decision flow for selecting VPA update mode: stateful workloads use Initial, stateless use Auto, all start in Off mode for validation.

When should you avoid using Vertical Pod Autoscaler?

VPA is powerful but not universal. Knowing its limitations prevents operational pain. Avoid VPA entirely for workloads with highly variable, unpredictable resource patterns (e.g., ML training jobs with random dataset sizes) — the 8-day histogram will lag behind reality. Similarly, skip it for pods using local storage without PVCs; eviction loses data. DaemonSets are unsupported because node affinity conflicts with VPA’s mutation logic.

Do not use VPA alongside Cluster Autoscaler without coordination. If VPA increases pod size beyond node capacity, Cluster Autoscaler may fail to scale up fast enough, causing pending pods. In multi-tenant clusters, VPA recommendations can be skewed by noisy neighbors sharing nodes. Isolate such workloads or use namespace-scoped VPAs with strict quotas. Finally, never enable VPA Auto mode on pods without readiness probes — evicted pods may receive traffic before warming caches, violating latency SLOs.

How does VPA compare to HPA and KEDA for autoscaling?

Understanding where VPA fits in the autoscaling ecosystem prevents redundant or conflicting configurations. While Vertical Pod Autoscaler (VPA) explained focuses on per-pod efficiency, HPA and KEDA handle throughput-driven replication. They solve orthogonal problems but require careful integration.

Autoscaling Dimensions ComparedVPAVertical ScalingPod SizeAdjusts CPU/MemoryPer ContainerEviction-BasedBest: Right-SizingHPAHorizontal ScalingReplicasAdds/Removes PodsCPU/Memory/CustomNon-DisruptiveBest: Traffic SpikesKEDAEvent-Driven ScalingTriggersQueue Depth/LagExternal MetricsScale-to-ZeroBest: Async WorkloadsComplementsExtends
VPA adjusts pod size vertically, HPA scales replicas horizontally, KEDA triggers scaling on external events — each serves distinct autoscaling needs.

Use VPA to establish efficient baselines, HPA to handle predictable load variations, and KEDA for event-driven bursts. In my experience managing Nepal-based fintech platforms with global users, this layered approach reduced compute costs by 22% while maintaining 99.95% availability. Always instrument with Prometheus metrics to validate that combined autoscalers aren’t fighting each other — e.g., HPA adding replicas while VPA shrinks them below effective thresholds.

Implementing Vertical Pod Autoscaler (VPA) Explained for Production Stability

Deploying Vertical Pod Autoscaler (VPA) explained correctly transforms guesswork into data-driven resource management. Start with Off mode, validate recommendations against golden signals, then graduate to Initial or Auto with safety guards. Monitor eviction rates, SLO compliance, and cost trends continuously. Remember: VPA optimizes efficiency, not availability. Pair it with robust observability, graceful shutdown handlers, and capacity buffers. If your team needs help designing autoscaling strategies that pass compliance audits and survive peak loads, reach out for a consultation.

Frequently Asked Questions

VPA automatically adjusts CPU and memory requests and limits for pods based on historical usage. It right-sizes workloads to reduce waste or prevent OOM kills without manual intervention.

No. HPA scales replica count; VPA scales resource size per pod.

Yes, but only if HPA targets custom metrics. Using HPA with CPU/memory metrics alongside VPA causes conflicting scaling decisions and resource thrashing in 2026 clusters.

Yes. In Auto mode, VPA evicts pods to apply new recommendations. Update mode requires manual rollout. Off mode provides recommendations only without enforcement or disruption.

Off generates recommendations only. Initial sets resources at creation time. Auto applies changes by evicting pods when recommendations deviate significantly from current requests or limits.

Check that the recommender and updater components are running. Verify the target workload matches the VPA selector exactly. Ensure metrics-server is healthy and providing data.

Yes. VPA supports Deployments, StatefulSets, DaemonSets, ReplicaSets, and Jobs. Configure the targetRef correctly with apiVersion, kind, and name fields matching your specific workload.

Typically eight hours minimum. The recommender needs sufficient metric history to calculate reliable percentiles. New deployments show no recommendations until this observation window completes.

Yes. Use containerPolicies minAllowed and maxAllowed fields to enforce guardrails. This prevents VPA from setting resources below critical thresholds or exceeding node capacity limits.

Yes. Right-sized pods improve cluster autoscaler efficiency by reducing over-provisioned nodes. However, frequent VPA evictions can trigger unnecessary scale-up events during bin-packing adjustments.

Yes, but start with Off or Initial mode. Monitor recommendations against actual performance before enabling Auto mode. Critical stateful services often prefer Initial mode to avoid unexpected evictions.

Inspect vpa-recommender logs for metric gaps. Check if application has memory leaks skewing percentile calculations. Compare VPA suggestions against Prometheus historical data to validate accuracy.

No. VPA only handles CPU and memory as of 2026. GPU scheduling requires separate device plugins and custom schedulers since extended resources lack native autoscaling support.

Yes. The updater component checks PDBs before evicting pods. If disruptions exceed allowed limits, VPA defers updates until the budget permits safe eviction.

VPA requires get, list, watch on pods and metrics, plus patch on pods/eviction. The updater needs create on events. Follow official manifests for least-privilege role bindings.