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 set requests from measured usage instead of over-provisioning. A deployment that requests `500m` but idles at `180m` is holding down 2.7x the CPU it needs. 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 has three parts: 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 its capability you use is the `updateMode`: - **`Off` (recommend only)** computes the numbers and does nothing else. You read the target and apply it through your manifests. - **`Auto` / `Recreate`** gives control to the updater: 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 conflict 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; each one’s action feeds the other’s input in a loop. 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; disruptive for a singleton with no replica to fail over to. That is the second reason to trust 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 unexpectedly. ## Read the recommendation This is the primary output: the requests the VPA recommends, for you to apply: ```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 improvement.