# GKE Node Pool VM-Size Rightsizing

> Every rung on the GCE ladder doubles vCPU, so halving a node pool's machine type roughly doubles its utilization. ZopNight therefore requires average node CPU under 50% and a trusted peak also under 50% before proposing the next-smaller same-family type, executed as a guided rolling node recreate.

Source: https://zop.dev/integrations/gcp/recommendations/gke-node-pool-vm-size-rightsizing
Updated: 2026-08-19

---

## A 2x step needs a 50% ceiling

GCE machine families step in powers of two (n1-standard-4 to n1-standard-2 halves the
vCPUs), so a pool moved one rung down runs at roughly double its previous utilization.
The generic 80% peak guard used by one-tier downsizes is dangerous here: a pool peaking
at 79% would land near 158% and throttle every pod on it. Both gates in this rule
therefore sit at 50%: the 30-day average must be below it to fire, and the peak must be
below it to survive the guard, preserving about 2x headroom through the halving.

## Trusted peaks only

The peak check refuses thin evidence. A maximum is only a true hourly peak once the
series carries at least 7 days of max-band coverage; below that it is a smoothed
peak-of-averages that systematically understates spikes. That data is biased toward exactly the
mistake the guard prevents. A young or sparsely-monitored pool fails closed. Rates for
the current and target machine types come from the live pricing catalog, and the saving
is cost × (current − target) ÷ current; a missing or inverted rate kills the
recommendation rather than shipping $0.

## The rolling recreate and its blast radius

Applying the change is one API call: GKE's UpdateNodePool with the smaller machine type,
which ZopNight's provisioner drives under the catalogued `container.clusters.update`
permission in `roles/container.clusterAdmin`. GKE then drains and recreates each node in
turn. That rolling recreate evicts every pod on the pool, which is why the remediation is
a guided wizard with a PodDisruptionBudget check in front of it rather than a silent
auto-fix.

## Read the pool's machine type

```bash
gcloud container node-pools describe my-pool --cluster my-cluster \
  --location us-central1 --format="value(config.machineType)"
```

Watch application latency for a day after the migration; the halved pool should settle
near double its old utilization, not at saturation.

## Families, customs, and floors

Custom shapes, shared-core types, GPU rungs, legacy families, and pools already at the
bottom of their ladder have no next-smaller target and never fire. Every emission names a
concrete catalog machine type; "use something smaller" is not a recommendation this rule
will make.
