kubernetesautoscalingcost-optimizationfinops

HPA vs VPA cost impact: which autoscaler actually lowers your Kubernetes bill

Horizontal and Vertical Pod Autoscalers solve different problems and have opposite cost behaviours. HPA can raise your bill while improving latency, VPA usually lowers it by shrinking requests. Here is how each affects the node count you pay for.

The C3X Team··7 min read

Quick answer

HPA changes replica count in response to load, so it saves money only if it scales down as aggressively as it scales up, and it saves nothing unless the cluster autoscaler then removes the freed nodes. VPA changes per-pod CPU and memory requests toward observed usage, which directly shrinks what the scheduler provisions and typically cuts node count by 25 to 45 percent in over-provisioned clusters. They conflict on the same metric, so the standard pattern is VPA for memory and requests plus HPA on a custom metric. VPA in recommendation-only mode is the safest first move and often identifies 30 percent of node spend as removable.

Both autoscalers have "autoscaler" in the name and people assume both save money. They do very different things. HPA adds and removes pod replicas. VPA changes how much each pod asks for. Only one of them directly attacks the gap between requested and used resources, which is where most Kubernetes waste lives.

What each one does to the bill

AutoscalerChangesCost effectTypical impact
HPAReplica countBoth directionsMinus 45 to plus 5 percent
VPAPer-pod requestsAlmost always downMinus 25 to 45 percent
Cluster AutoscalerNode countDown, if pods allowRealizes the other two

The critical dependency: neither pod autoscaler saves a cent on its own. Kubernetes bills nodes. Shrinking pods or removing replicas only saves money when the node autoscaler then removes nodes, which requires the remaining pods to consolidate. Teams frequently run HPA and VPA with no node-level consolidation and wonder why the bill did not move.

HPA can increase cost

HPA's job is meeting a target utilization, usually CPU at 50 to 70 percent. If a service was pinned at 3 replicas and load routinely pushed it to 90 percent CPU, HPA will scale it to 5 or 6 replicas to hit a 60 percent target. That is better for latency and worse for the bill. HPA is a performance tool with cost side effects, not a cost tool.

Where HPA does save is variable load. A service sized statically for peak runs peak capacity 24 hours a day. With HPA and a traffic curve that peaks for 6 hours and troughs for 10, the average replica count drops. A service statically at 20 replicas of 1 vCPU costs $778 per month in node capacity at $38.89 per requested vCPU. With HPA ranging 6 to 22 and averaging 11, it costs $428, a 45 percent saving, but only if the cluster autoscaler reclaims the nodes at trough.

ConfigurationAverage replicasvCPU requestedMonthly node cost
Static at peak2020$778
HPA 6 to 22, spiky traffic1111$428
HPA 18 to 24, flat traffic2121$817

Note the third row. On flat traffic HPA costs slightly more than a well-chosen static count, because stabilization windows and target headroom bias it upward. Do not enable HPA on flat-traffic services and expect savings.

VPA attacks the real waste

VPA observes actual container usage and recommends or applies right-sized requests. Since therequests versus usage gap is typically 2.5 to 3.5 times on CPU, VPA's recommendations often cut requested capacity by a third or more. That directly reduces how many nodes the scheduler needs.

The catch is the update mechanism. VPA in Auto or Recreate mode evicts a pod to resize it, since in-place resource resize only became broadly usable in recent Kubernetes versions. Eviction on a singleton pod is a restart, which is why VPA has a reputation for being disruptive. Start in updateMode Off, which generates recommendations without touching anything, and feed those numbers into your manifests through normal review. That captures most of the saving with none of the churn.

Why they conflict

Running HPA and VPA on the same CPU metric creates a loop. VPA shrinks the CPU request, which raises measured CPU utilization as a percentage of request, which makes HPA add replicas, which lowers per-pod utilization, which makes VPA shrink further. The supported combinations are VPA on memory with HPA on CPU, or HPA on a custom or external metric such as queue depth or requests per second with VPA handling both CPU and memory.

The configuration that actually saves money

LayerSettingWhy
VPAupdateMode Off, applied via reviewRight-sizes requests safely
HPAOnly on variable-load servicesAvoids raising flat workloads
HPA minReplicasAs low as availability allowsTrough savings come from here
HPA scale-down window5 to 10 minutes, not 30Long windows erase trough savings
Node consolidationAggressive scale-down or KarpenterTurns pod savings into node savings

The default HPA scale-down stabilization window is 300 seconds, which is reasonable. Teams that raised it to 30 minutes after a flapping incident effectively disabled trough savings, since most traffic dips do not last 30 minutes. Fix flapping with better target values and a gentler scale-up policy instead.

Finally, remember the realization step. Pod-level savings become real money only when node groups shrink, and node group sizing lives in Terraform. Price it against the resource catalog so the capacity you remove after a VPA rollout is visible as a monthly number rather than a hopeful assumption, and pair it withpod right-sizing as an ongoing practice.

FAQ

Does HPA save money in Kubernetes?

Only on variable-load services, and only if the cluster autoscaler then removes the freed nodes. A service statically sized at 20 replicas costs about $778 per month in node capacity, while HPA ranging 6 to 22 on spiky traffic averages 11 replicas and $428, a 45 percent saving. On flat traffic HPA typically costs slightly more than a well-chosen static count because of target headroom and stabilization windows.

Does VPA reduce Kubernetes cost?

Usually yes, and more reliably than HPA. VPA sets per-pod CPU and memory requests from observed usage, and since the requests-to-usage gap is typically 2.5 to 3.5 times on CPU, its recommendations often cut requested capacity by a third or more. That directly reduces how many nodes the scheduler needs, commonly 25 to 45 percent in over-provisioned clusters.

Can I run HPA and VPA together?

Not on the same metric. VPA shrinking the CPU request raises measured CPU utilization as a percentage of request, which makes HPA add replicas, which lowers per-pod utilization, which makes VPA shrink further. The supported combinations are VPA on memory with HPA on CPU, or HPA on a custom metric such as queue depth or requests per second with VPA handling both CPU and memory.

Is VPA safe to enable in production?

Start in updateMode Off, which generates recommendations without changing anything. VPA in Auto or Recreate mode evicts pods to resize them, which is a restart for singleton workloads and is why VPA has a reputation for disruption. Reading the recommendations and applying them through normal manifest review captures most of the saving with none of the churn.

Why did enabling autoscaling not reduce my Kubernetes bill?

Because Kubernetes bills nodes, not pods. Shrinking pod requests or removing replicas saves nothing until the cluster autoscaler removes the freed nodes, which requires remaining pods to consolidate onto fewer nodes. Common blockers are a scheduler profile that spreads pods, missing PodDisruptionBudgets, anti-affinity rules, and a scale-down utilization threshold set too conservatively.

How does C3X help with Kubernetes autoscaling cost?

Autoscaling only turns into savings when node groups shrink, and node group sizing lives in Terraform. C3X prices those definitions against a live catalog so the capacity removed after a right-sizing or autoscaling rollout shows as a concrete monthly figure in the pull request, rather than a hoped-for improvement nobody verifies on the invoice.

What to do next

Turn autoscaling into a number on the bill. C3X reads your Terraform and prices your resources against a live catalog. Start with the quickstart.

Try C3X on your own Terraform

Free and open source. No API key required. One command to install, one command to estimate.