# Cloud Run Dev/Test Service Has Min Instances > 0

> Cloud Run services with dev/test evidence and minInstances above 0 are told to set --min-instances=0. Savings price the always-warm capacity being removed: minInstances times the per-second vCPU and memory warm rates times seconds per month, capped at cost; a prod label or missing rates abstains.

Source: https://zop.dev/integrations/gcp/recommendations/cloud-run-dev-test-service-has-min-instances-0
Updated: 2026-08-19

---

## Where minInstances and the env label live

- resource.Metadata: minInstances (via getMetaFloat; producer asset_inventory.go:3159 enrichGCPCloudRun writes it from the autoscaling.knative.dev/minScale annotation, the same key cloudrun_idle.go uses). The prior tag: min_instances was a dead contract (item T0295).
- resource.Tags: env tag (env/environment/stage/tier): authoritative prod veto (isProdEnvTag) AND positive dev/test evidence (isDevTestEnvTag). Kept for parity with providers where env genuinely lives in Tags, but on Cloud Run the discoverer never writes env into Tags (only max_concurrency), so this reader is always empty on real GCP data.
- resource.Metadata: nested labels.env (env/environment/stage/tier), the actual GCP producer sink (asset_inventory.go genericEnrichGCPLabels writes customer labels under Metadata["labels"], never Tags). Read via isProdEnvLabel/isDevTestEnvLabel (gke_spot_nodepool.go helpers), OR'd with the Tags-based checks above so the prod veto and dev/test evidence gates are no longer dead on live Cloud Run data.
- resource.Name: dev/test pattern (dev, test, qa, staging, sandbox): positive dev/test evidence (isDevTestName), but no longer name-sole: a prod-looking name or env=prod tag/label vetoes first.
- resource.Metadata: cpu + memory (asset_inventory.go:3706/3710, Knative quantity strings)
- PricingAware + SKURatesAware: per-resource monthly cost + cloudrun-cpu-second / cloudrun-mem-gib-second per-second warm-capacity rates

## Pricing the always-warm capacity you remove

concrete-or-abstain (cost-driven rightsizing). The prior advisory/SavingsUSD=0 (and earlier 0.30 fraction) posture is removed. savings = minInstances × (vcpu×cpuSecondRate + memGiB×memSecondRate) × secondsPerMonth, capped at cost, the identical idle-warm formula sibling RC-149 uses on the same resource type and minInstances key; scaling min→0 removes exactly this always-allocated warm component, request-served capacity unaffected. Abstains (returns nil, never $0) when not dev/test, minInstances ≤ 0, no/zero pricing, vCPU/memory absent/unparseable, or either per-second rate missing.

## Setting min instances back to zero

1. Update the Cloud Run service to set --min-instances=0
