# Idle GCP VM Instance

> GCE VMs averaging below 5% CPU over 30 days receive a recurring off-hours schedule when the aggregator's heatmap measures a real idle window; savings equal cost times that measured idle percentage. Critical-role and stateful- workload names are vetoed, and missing schedule data or pricing means the rule abstains.

Source: https://zop.dev/integrations/gcp/recommendations/idle-gcp-vm-instance
Updated: 2026-08-19

---

## CPU idleness plus the DR and database vetoes

- resource.Status: statusTerminated
- MetricsAware (SetMultiMetrics): gcpCPUMetricName (CPUUtilization) read by name off the nested UID→metricName view over gcpCPULookbackDays days (Bug-1: compute harvests 9 metrics, so a bare-UID read would be CPU only ~1/9 of the time); abstains when the named series is absent.
- ScheduleAware (SetScheduleData): the aggregator's heatmap-derived model.ScheduleData (same RC-093/RC-110 path) keyed by UID, carrying the measured off-hours IdlePercentage.
- Skip when the VM already carries a schedule tag (intentionally parked, not abandoned).
- Critical-role veto (matchesCriticalRole, shared with RC-110/RC-111): abstains on a DR/backup/standby-named VM, which must stay ready to absorb production traffic on failover even when CPU-idle.
- Stateful-workload veto (matchesStatefulWorkload, shared with RC-110/RC-111): abstains on a self-managed database/cache/broker VM (via discoverer engine/tier Metadata, data-tier Tags, or a boundary-matched name token): the heatmap's CPU/inbound-network/disk idle window cannot prove a durable-state, typically single-replica service is safe to park.

## A 5% CPU floor over 30 days

```text
gcpCPUThreshold=5.0, gcpCPULookbackDays=30
```

## Savings scaled by the measured off-hours window

concrete-or-abstain (cost-driven schedule). When the VM is CPU-idle, is not a critical-role/stateful-workload VM, and the aggregator's heatmap shows a measured off-hours window, savings = cost × ScheduleData[uid].IdlePercentage, optimized = cost − savings; the lever is a recurring off-hours schedule (never a one-shot stop/terminate, never a single-axis CPU rightsize since memory is unobservable on GCE). The rule abstains (returns nil) when pricing is unknown/zero, no measured schedule data exists, or the critical-role/stateful-workload veto fires. There is no $0 advisory and no fabricated flat fraction. (Was previously documented as advisory/$0; reworked under the 2026-06-27 concrete-or-abstain directive; critical-role/stateful-workload vetoes added to close the gap where RC-102 was the only sibling of RC-110/RC-111 without them.)

## Applying the recurring off-hours schedule

1. Review the recommended off-hours schedule (Start / Stop / Timezone)
2. Apply it from this recommendation (recurring off-hours park, not a one-shot stop)

## A single CPU series read by name

gcpCPUMetricName (gcpCPULookbackDays day lookback)
