Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler

Khimananda Oli 8 min read Database
Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler

By Khimananda Oli | Last reviewed: August 2026

Misconfigured scaling is the silent killer of cloud budgets and application reliability. You need a comprehensive strategy for Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler to handle variable workloads without over-provisioning or crashing under load. If you are building on cloud infrastructure, understanding these three distinct mechanisms is mandatory before you attempt to reduce your AWS bill with cloud cost optimization tactics.

Kubernetes Scaling DomainsPod Level (Workload)HPA: Replica CountVPA: CPU / Memory RequestsNode Level (Infrastructure)Cluster AutoscalerAdd/Remove EC2/VM NodesMetrics ServerSource of Truth for CPU/Mem
Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler operate across pod and node layers with Metrics Server as the data source

How does Horizontal Pod Autoscaler (HPA) work in production?

The Horizontal Pod Autoscaler is the most commonly used component in Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler workflows. It watches metrics from the Metrics Server and adjusts the number of pod replicas in a Deployment, StatefulSet, or ReplicaSet. In practice, HPA is your first line of defense against traffic spikes.

Configuring HPA with custom metrics

CPU utilization alone is rarely sufficient for modern applications. Most web services are memory-bound or latency-sensitive. You should configure HPA using multiple metrics to prevent premature scaling or dangerous under-scaling. Here is a production-grade HPA manifest that targets both CPU and memory:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-service-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-service
  minReplicas: 3
  maxReplicas: 20
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Pods
          value: 4
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Pods
          value: 2
          periodSeconds: 120
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 75

The behavior block above is critical. Without it, HPA reacts too aggressively to transient spikes, causing unnecessary pod churn. The 300-second scale-down stabilization window prevents flapping when traffic dips momentarily. Always set explicit minReplicas higher than 1 for production workloads; a single replica during a node failure means downtime regardless of how fast HPA responds.

Common HPA mistakes

  • Missing resource requests: HPA cannot calculate utilization percentages if containers lack resources.requests. The autoscaler will remain idle and log warnings.
  • Setting maxReplicas too low: During DDoS attacks or viral events, hitting the ceiling causes request queuing and 5xx errors. Set maxReplicas based on load test results, not guesses.
  • Ignoring startup time: If your application takes 60 seconds to become ready, rapid scaling creates a thundering herd. Pair HPA with readiness probes and consider KEDA for event-driven pre-scaling.

When should you use Vertical Pod Autoscaler (VPA)?

VPA adjusts the CPU and memory requests and limits of individual containers rather than changing replica counts. Within Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler, VPA serves a fundamentally different purpose: right-sizing. Most teams deploy VPA in recommendation mode first to gather data before enabling automatic adjustments.

VPA modes and safe rollout

VPA operates in three modes, and choosing incorrectly can cause outages:

  1. Off (Recommendation Only): VPA observes workloads and suggests optimal resource values via the vpa describe command. No changes are applied. Start here for at least one week.
  2. Initial: Resources are set only at pod creation time. Existing pods keep their current values. Safe for stateful workloads but requires manual restarts to apply recommendations.
  3. Auto: VPA evicts pods to apply new resource values. This causes brief unavailability. Never enable Auto mode without PodDisruptionBudgets and multi-replica deployments.
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: worker-vpa
  namespace: production
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: background-worker
  updatePolicy:
    updateMode: "Auto"
    minReplicas: 2
  resourcePolicy:
    containerPolicies:
      - containerName: worker
        minAllowed:
          cpu: 100m
          memory: 128Mi
        maxAllowed:
          cpu: 4
          memory: 8Gi
        controlledResources: ["cpu", "memory"]

The minAllowed and maxAllowed fields act as guardrails. Without them, VPA might recommend dangerously low values during quiet periods or excessive resources during anomalous spikes. In my experience auditing clusters for SOC 2 compliance, unbounded VPA configurations are a frequent finding because they introduce unpredictable resource consumption that violates capacity planning documentation.

How do HPA and VPA interact without conflicts?

This is where most implementations fail. HPA and VPA can fight each other if misconfigured. HPA scales horizontally based on utilization percentages, while VPA changes the denominator (resource requests) that HPA uses for its calculations. When VPA increases memory requests, utilization drops, potentially triggering HPA scale-down even though actual load hasn't changed.

Metrics ServerHPA ControllerVPA RecommenderPodsCPU/Mem UsageScale Replicas (Horizontal)Historical MetricsEvict & Resize (Vertical)Conflict ZoneVPA resize → Utilization shift → HPA miscalculation
HPA and VPA interaction sequence showing the conflict zone where vertical resizing affects horizontal scaling decisions

To avoid this feedback loop, follow these rules:

  • Never use VPA Auto mode with HPA on the same metric. If HPA scales on CPU, let VPA manage only memory, or vice versa.
  • Use VPA in Off mode alongside HPA. Apply VPA recommendations manually during maintenance windows after reviewing trends.
  • Prefer KEDA for event-driven workloads. For queue-based workers, external metrics (queue depth) decouple scaling from resource utilization entirely, eliminating the HPA/VPA conflict.

How does Cluster Autoscaler provision nodes efficiently?

While HPA and VPA optimize within existing capacity, Cluster Autoscaler ensures that capacity exists. It monitors for unschedulable pods and provisions new nodes from cloud provider auto-scaling groups. When nodes are underutilized for an extended period, it consolidates workloads and terminates excess instances. This component completes the Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler stack by bridging application demands with infrastructure supply.

Tuning scale-down thresholds

The default Cluster Autoscaler configuration is too conservative for cost-sensitive environments and too aggressive for stability-critical ones. Key flags to tune:

# Helm values for cluster-autoscaler
extraArgs:
  scale-down-delay-after-add: 10m
  scale-down-unneeded-time: 5m
  scale-down-utilization-threshold: 0.6
  max-graceful-termination-sec: 600
  skip-nodes-with-local-storage: true
  balance-similar-node-groups: true

The scale-down-utilization-threshold of 0.6 means nodes below 60% utilization are candidates for removal. Raising this to 0.7 saves money but increases scheduling latency during traffic ramps. The balance-similar-node-groups flag is essential for multi-AZ deployments; without it, Cluster Autoscaler may concentrate nodes in a single availability zone, creating a resilience gap that will surface during your next disaster recovery test.

Which autoscaler should you choose for your workload?

Selecting the right tool depends on your workload characteristics, not hype. Reference this comparison when designing your scaling strategy or preparing for a Kubernetes basics deployment:

CriteriaHPAVPACluster Autoscaler
Primary FunctionAdjust replica countAdjust resource requests/limitsAdd/remove cluster nodes
Best ForStateless web APIs, microservicesBatch jobs, databases, right-sizingCloud-native clusters, variable base load
Scaling DirectionHorizontal onlyVertical onlyInfrastructure horizontal
Downtime RiskLow (new pods added)Medium-High (pod eviction in Auto mode)Low (graceful drain)
Metrics DependencyCPU, Memory, Custom, ExternalHistorical CPU/Memory usageScheduler pending pods
Cost ImpactModerate (more pods = more resources)High (eliminates over-provisioning waste)Highest (directly controls node spend)
Setup ComplexityLowMediumHigh (cloud provider integration)

For most production applications, start with HPA and Cluster Autoscaler. Add VPA only after collecting two weeks of metrics data and identifying consistent over-provisioning. Teams running Helm-managed Kubernetes deployments should package autoscaler configurations as chart dependencies to ensure consistency across staging and production environments.

Workload AnalysisTraffic pattern variable?YesNo (Steady)Enable HPAUse VPA (Off Mode)Nodes exhausted?Over-provisioned >30%?YesYesAdd Cluster AutoscalerApply VPA Recommendations
Decision flowchart for selecting the appropriate Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler component based on workload characteristics

Implementing Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler Securely

Autoscaling introduces dynamic behavior that complicates security and compliance. From my experience preparing infrastructure for ISO 27001 audits, these controls are non-negotiable:

  • RBAC for autoscalers: Restrict HPA and VPA service accounts to specific namespaces. A compromised autoscaler with cluster-wide permissions can escalate privileges by manipulating resource quotas.
  • Resource quotas and LimitRanges: Always define namespace-level quotas to cap maximum autoscaling. Without them, a misconfigured HPA with maxReplicas: 1000 can exhaust your entire cloud budget in minutes.
  • Audit logging: Enable Kubernetes audit logs for autoscaling events. SOC 2 auditors will request evidence that scaling actions correlate with legitimate traffic patterns, not exploitation.
  • Prioritized classes: Configure PriorityClasses so autoscaling respects workload importance. Batch jobs should never preempt customer-facing API pods during resource contention.

Monitor your autoscalers themselves. Deploy Prometheus alerts for HPA reaching maxReplicas, VPA eviction frequency exceeding thresholds, and Cluster Autoscaler failures. If you haven't established observability yet, follow this Prometheus and Grafana monitoring setup guide before enabling aggressive autoscaling policies.

Next Steps for Production Scaling

Kubernetes Autoscaling: HPA, VPA and Cluster Autoscaler form a complete system only when configured with discipline. Start with HPA using conservative thresholds and explicit stabilization windows. Collect VPA recommendations passively before applying changes. Tune Cluster Autoscaler scale-down parameters to match your cost-stability tolerance. Document every decision for future audits and team handoffs. If your team needs help designing a compliant, cost-efficient autoscaling architecture, reach out to discuss your infrastructure requirements.

Frequently Asked Questions

HPA adjusts pod replica counts based on metrics like CPU or memory. VPA modifies resource requests and limits for existing pods without changing replica count. Use HPA for horizontal scaling and VPA for right-sizing individual container resources efficiently.

Yes, but configure VPA in recommendation mode only to avoid conflicts. Let HPA handle replica scaling while using VPA suggestions to manually adjust resource requests. Running both in automatic mode simultaneously causes scaling loops and resource contention in 2026 clusters.

It monitors pending pods that cannot be scheduled due to insufficient resources. When detected, it provisions new nodes matching configured instance groups. The scaler also removes underutilized nodes after a configurable grace period to optimize cloud spending.

Prefer custom application metrics over raw CPU or memory. Use Prometheus Adapter to expose request latency, queue depth, or throughput. These reflect actual user load better than system metrics and prevent premature scaling during background processing spikes.

Check if metrics-server is running and returning valid data. Verify HPA target utilization thresholds are not set too high. Confirm deployments have resource requests defined, as HPA cannot calculate utilization percentages without baseline resource specifications.

Yes, VPA in auto mode recreates pods to apply new resource values. This causes brief downtime per pod. Use off-hours update windows or combine with PodDisruptionBudgets to minimize impact during resource adjustment cycles.

Add the safe-to-evict annotation set to false on pods that must stay. Alternatively, use node taints or priority classes to protect system workloads. Configure scale-down delay to allow transient load spikes before triggering node removal.

Set scale-up stabilization to zero seconds for responsive scaling. Configure scale-down stabilization between three and five minutes to prevent flapping. This balances rapid response to traffic surges with cost efficiency during gradual load decreases.

Yes. KEDA extends HPA with event sources like Kafka, SQS, or cron. It scales from zero and supports external metrics natively. Use KEDA when workload depends on message queues rather than HTTP traffic or CPU utilization.

Use kubectl debug or staging namespaces with identical resource quotas. Simulate load with tools like Locust or k6. Monitor HPA events and VPA recommendations via kubectl describe to validate behavior matches expected scaling patterns.

Short observation windows capture outlier spikes as baseline. Increase the VPA updater interval and use percentile-based recommendations. Filter out initialization phases by setting minAllowed values to prevent cold-start anomalies from inflating long-term resource targets.

It supports AWS, GCP, Azure, and major providers via cloud-provider plugins. Verify your provider plugin version matches your Kubernetes version. Some managed services offer native integrations like EKS Karpenter or GKE Autopilot that supersede standard Cluster Autoscaler.

Export HPA and Cluster Autoscaler metrics to Prometheus. Track scaling events, pending pod duration, and node utilization rates. Correlate with cloud billing APIs to measure cost-per-request trends and identify over-provisioned periods requiring policy tuning.

Minimal RBAC roles for reading pods, nodes, and replication controllers. Cloud provider credentials limited to instance group management. Never grant cluster-admin. Use workload identity or IRSA in 2026 to bind autoscaler service accounts to scoped cloud roles.

No. HPA scales pods, not nodes. Karpenter replaces Cluster Autoscaler with faster, bin-packing-aware node provisioning. Combine HPA for pod replicas with Karpenter for efficient node lifecycle management and reduced waste in dynamic environments.