> ## Documentation Index
> Fetch the complete documentation index at: https://docs.costgraph.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Vertical Pod Autoscaler

> Let a Vertical Pod Autoscaler apply CostGraph AutoPilot sizing.

With `autopilot.costgraph.ai/via: vpa`, CostGraph supplies the recommendation and
a Vertical Pod Autoscaler (VPA) applies it. Use it when you already run the VPA
components and prefer them to the CostGraph admission webhook.

## Requirements

* The VPA CRD, updater and admission controller installed in the cluster (VPA 1.6 or later). If they are missing, the workload shows "VPA not installed" and nothing is created. The updater and admission controller are found by their Deployment names (for example `vpa-updater` and `vpa-admission-controller`), so a VPA that your cloud provider runs in its managed control plane can show "VPA not installed". Use the webhook there.
* `global.autopilot.vpa.enabled=true` on the operator chart. It is off by default, and the permissions the operator needs for VPAs are granted only when it is on.

```bash theme={null}
helm upgrade costgraph-operator costgraph/costgraph-operator \
  --reuse-values \
  --set global.autopilot.enabled=true \
  --set global.autopilot.vpa.enabled=true \
  --set global.autopilot.defaultVia=vpa
```

## How it works

For each annotated workload, CostGraph creates a VPA labelled
`costgraph.ai/managed: "true"` and writes its recommendation to the VPA. The
update mode follows the `mode` annotation:

| `mode` | VPA update mode |
| - | - |
| `auto` | `InPlaceOrRecreate` |
| `initial` | `Initial` |
| `off` | `Off` |

The VPA is limited to the resources and containers allowed by `resources`,
`exclude-containers` and the maximum bounds. Its maximum is capped to what the
workload's node pool can launch, so a recommendation never exceeds the largest
node.

Pods that are not Guaranteed have only their requests changed. Guaranteed pods
keep request equal to limit, so both move together, and memory is never lowered:
a memory reduction is held and shown with the reason.

CostGraph deletes the VPA when you remove the annotation. It only deletes VPAs
that it created.

## Behaviour to know about

* **A VPA applies the last recommendation indefinitely.** If CostGraph has not sent a fresh recommendation within `global.autopilot.staleAfter` (30 minutes by default), CostGraph switches its VPAs to `Off`.
* **`mode: auto` can evict pods.** `InPlaceOrRecreate` resizes in place when it can, and recreates the pod when a resize is not possible or is deferred for a long time.
* **Pods that must not be disrupted stay on `Initial`.** A workload whose pods carry `karpenter.sh/do-not-disrupt` is kept on `Initial` even with `mode: auto`, so its pods are never evicted.
* **Turning the VPA path off leaves VPAs behind.** If you set `global.autopilot.vpa.enabled` to `false` after it was on, delete the VPAs CostGraph created with `kubectl delete vpa -A -l costgraph.ai/managed=true`.
* **Your own VPA wins.** A workload targeted by a VPA that CostGraph did not create is skipped. On the VPA path it is shown as "Has own VPA". It is never taken over.
* **One mechanism per workload.** The CostGraph webhook skips any workload with a VPA.

## What is not available with a VPA

These are available only with the webhook:

* GPU sizing and pool placement
* Sizing of Jobs and CronJobs (shown as "Job on VPA path" on the VPA path)
* Instant out-of-memory bumps
* Rollback and pacing of changes


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.