# Stopped Standalone GCE VM

> TERMINATED standalone GCE VMs pay $0 for compute but keep billing attached persistent disks and reserved static IPs. Savings sum the priced monthly cost of those residual children, broken down per component; when no child matches or none carries a positive price, the rule abstains.

Source: https://zop.dev/integrations/gcp/recommendations/stopped-standalone-gce-vm
Updated: 2026-08-19

---

## Terminated, with no parent group

GCE VM with Status = TERMINATED and no ParentUID (excludes MIG / GKE node-pool members whose lifecycle is parent-managed).
- resource.Status: must be TERMINATED
- resource.ParentUID: must be empty (standalone, not MIG-managed)
- ResourceContextAware (SetResources): the full org resource set, so the rule can find the VM's attached-disk / reserved-static-IP child resources (matched by ParentUID, normalized via normalizeComputeUID to bridge the raw asset-name vs. //compute.googleapis.com/... link form).
- PricingAware (SetPricing): per-resource monthly cost keyed by UID, used to price each child.

## The residual disks and static IPs still billing

concrete-or-abstain (Category orphan, which is exempt from shouldDropLowSavings). Compute is \$0 for a TERMINATED VM, so the deletable saving is the residual: residual = Σ cost[child] over every attached child (persistent disks + reserved static IPs) with a positive priced cost, so CurrentCostUSD = SavingsUSD = residual, OptimizedCostUSD = 0. The child-type gate is the shared model.IsResidualCostChildType (also used by the org engine's cross-chunk residual pricing, so the fold and pricing can't drift). SavingsBreakdown itemises the residual into Persistent disk + Static IP components (summing to SavingsUSD) for the UI, at parity with RC-001. Abstains (returns nil) when resources/pricing were not injected, no child matched, or every child is unpriced/zero: never a $0 or advisory rec, never a fabricated fraction of compute. (Was previously documented as advisory-only / not auto-remediable; reworked under the 2026-06-27 concrete-or-abstain directive.)

## Deleting the VM and its leftovers

1. Check whether the VM is intentionally stopped (e.g., long-running batch worker).
2. If no longer needed, delete the VM. Confirm attached disks have autoDelete enabled, or delete them separately.
3. Release any reserved static external IPs.
4. If the VM should be running, restart via gcloud compute instances start.
