Skip to main content

Right-size with the Vertical Pod Autoscaler

Inspect 1.36

The changes how many pods you run. The Vertical Pod Autoscaler changes how big each one is. It reads what a workload actually uses and tells you the CPU and memory requests it should have asked for, so you stop guessing, and stop padding requests "just in case." A deployment that requests 500m but idles at 180m is holding down 2.7x the CPU it needs. On hardware you pay for by the machine, that reserved-but-empty headroom is what pushes you into buying the next node early. The VPA is not part of the platform. Install it, then point it at a workload.

Three parts, two ways to run it#

The VPA is a recommender that watches usage and computes a target, an updater that evicts pods so they restart with new requests, and an admission controller that stamps those requests onto pods as they are created. How much of that machinery you switch on is the updateMode:

  • Off (recommend only) computes the numbers and touches nothing. You read the target and apply it through your manifests. Start here.
  • Auto / Recreate hands the updater the wheel: it resizes pods for you, which means restarting them.
yaml
		apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: web
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  updatePolicy:
    updateMode: "Off" # recommend only
	

Do not run VPA and HPA on the same metric#

The two autoscalers fight if they share a signal: an HPA scaling on CPU adds replicas when CPU is high, while a VPA in Auto mode raises the CPU request at the same time, and they chase each other. Keep them apart: HPA on CPU or memory, VPA in Off (recommend-only) mode for the same workload, or VPA on memory while the HPA scales on a custom metric. The clean pattern is HPA for scaling out and VPA in recommend-only mode to inform the requests you set.

Applying recommendations means restarts#

In Auto mode the VPA does not edit a running pod in place. Instead, it evicts the pod and lets it come back with the new requests. Fine for a stateless service with a PodDisruptionBudget and decent spread; brutal for a singleton that has nowhere to move. That is the second reason to lean on recommend-only mode: you take the same numbers and roll them out on your own schedule, through a normal deploy, instead of letting a moving recommendation restart pods under you.

Read the recommendation#

In recommend-only mode this is the whole payoff. The number the VPA settled on, waiting for you to apply it:

		$ kubectl describe vpa web
...
  Recommendation:
    Container Recommendations:
      Container Name:  app
      Target:
        Cpu:     180m
        Memory:  240Mi
	

Target is what the VPA would request per container. Compare it with what you actually declared. A wide gap either way is the right-sizing win you came for.