# GKE Spot Node Pool Opportunity

> Spot VMs run the same machine types at roughly 70% below on-demand list price, with preemption as the trade. ZopNight recommends Spot node pools only for dev/test-classified pools, checks the pool is not already Spot, and derives the fraction from live on-demand and Spot rates when available.

Source: https://zop.dev/integrations/gcp/recommendations/gke-spot-node-pool-opportunity
Updated: 2026-08-19

---

## Preemption is the price of 70% off

Spot VMs are the same machines at a baseline of roughly 70% below on-demand, and Google
can reclaim them with 30 seconds' notice. Kubernetes is unusually good at absorbing that:
evicted pods reschedule automatically, which is why the node pool, not the individual
VM, is the natural Spot unit for dev and test clusters. CI runners, preview
environments, and batch workers rarely notice a preemption; a developer waiting on a
rescheduled pod for a minute is a fine trade for the discount.

## Labels decide eligibility, names help

Classification runs on three signals: a dev/test-shaped pool name, a dev/test-shaped
cloud-account name, or a dev/test value in the env-style label the discoverer captures
from the pool's nested labels. The production veto reads the same label axis and wins
over everything: a pool labeled env=prod is never offered Spot regardless of its name,
because preempting production pods is an incident, not a saving.

## Already-Spot pools are skipped

The discoverer records `spot=true` on pools already running Spot capacity, and the rule
skips them. An earlier revision read a label sink GCP never populates and would happily
re-recommend Spot on a pool already on it, claiming savings that did not exist. The
current gate reads the sink the producer actually writes. When live on-demand and Spot
tier rates are present, the fraction is derived from them; otherwise the documented 70%
baseline applies to the pool's known cost.

## Check a pool's Spot flag

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

Migration is create-new, drain-old: stand up a Spot pool with the same configuration,
cordon and drain the on-demand pool, delete it once workloads settle.

## The per-pool pricing caveat

Node pools carry no cost of their own in the calculated path (member VMs are priced
individually to avoid double-counting), so on live fleets the per-VM Spot rule usually
carries the dollars while this rule contributes the pool-level signal. The eligibility
and already-Spot logic above is what fires the moment a pool-level cost basis exists.
