Min instances pinned above zero on a Cloud Run service nobody calls
What does ZopNight detect here?
Pinning minimum instances above 0 keeps Cloud Run billing CPU and memory every second of the month. ZopNight flags services whose CloudRunRequestCount average stays under 0.001 across 30 days and prices the pinned warm capacity at 2,592,000 billable seconds per month, recommending a reversible scale to zero.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-149 |
| Category | idle |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | cloudrun_idle.go |
Where it applies
Why minScale is a standing bill
Cloud Run’s headline economics, where you pay only while serving, stop applying the moment
the autoscaling.knative.dev/minScale annotation goes above zero. Each pinned instance is
held warm around the clock and billed for its full CPU and memory allocation across all
2,592,000 seconds of a month, whether one request arrives or none do. Teams usually pin
min instances to kill cold starts on a service that mattered once; the annotation then
outlives the traffic.
The traffic bar is nearly absolute zero
The rule reads the CloudRunRequestCount series for the service over 30 days and fires
only when the average sits below 0.001. Because of how the aggregator aligns this delta
counter, the effective bar is even stricter than the nominal one-request-per-17-minutes it
implies. The rule under-fires rather than over-fires, which is the safe direction for a
scale-to-zero recommendation. The metric read requires monitoring.timeSeries.list,
granted through roles/monitoring.viewer at project scope.
What scaling to zero actually changes
Only the idle-warm component goes away. Request-driven autoscaling is untouched: traffic
still spins instances up on demand, and the priced saving is exactly
minInstances × (vCPU rate + memory rate) × seconds per month, capped at the service’s
total bill. The executor applies it as a min-instances patch through run.services.get
and run.services.update (roles/run.developer). That is a reversible configuration change,
not a power-off. The trade you accept back is the cold start you originally paid to avoid.
Check the annotation yourself
gcloud run services describe my-service --region us-central1 \ --format="value(spec.template.metadata.annotations)" | tr ';' '\n' | grep minScalePair it with a look at the request graph in the console before deciding the service is genuinely unused rather than seasonally quiet.
Situations that produce no recommendation
Abstention is explicit: no recommendation is emitted when min instances is zero already, when the service’s cost is unknown or zero, when the request metric was never harvested, when traffic clears the idle floor, when the CPU or memory shape strings fail to parse, or when either Cloud Run per-second rate is missing from the pricing feed. A missing signal is never treated as idleness.