The [Horizontal Pod Autoscaler](/docs/hetzner/apalla/workloads/scaling/horizontal-pod-autoscaler) 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: ```console $ 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.