# GCP Cloud Run Service With Idle Min Instances

> 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.

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

---

## 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

```bash
gcloud run services describe my-service --region us-central1 \
  --format="value(spec.template.metadata.annotations)" | tr ';' '\n' | grep minScale
```

Pair 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.
