Staged rollouts are the safest way to ship an Android release. Push to 1% of users, check crash rates, bump to 5%, check again, then gradually ramp to 100%. Google Play has supported this for years.
The monitoring part, though? That's still manual for most teams. Open the Play Console, navigate to the vitals dashboard, eyeball the crash rate, compare it to last week, decide whether to proceed. Repeat every few hours across a multi-day rollout.
This article walks through automating that loop with a single terminal command.
The setup
You need:
- GPC (Google Play Console CLI) v0.9.67+
- A Google Play service account with access to the Reporting API
Install:
npm install -g @gpc-cli/cli
# or Homebrew
brew install yasserstudio/tap/gpc
# or standalone binary (no Node.js)
curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/install.sh | sh
Authenticate:
gpc auth login --service-account path/to/key.json
gpc doctor # verify everything works
Basic monitoring
After pushing a release to production, start watching:
gpc watch
That's it. GPC polls the Google Play API every 15 minutes by default, fetching two things:
- Rollout status (near real-time): version code, user fraction, track, release status
- Vitals data (24-48h delayed): crash rate and ANR rate averaged over 7 days
Each round prints the current state:
[14:30:02] Round 1
Rollout: v142 at 10% (inProgress)
crashes: 1.2% (threshold: 2.0%) OK
anr: 0.3% (threshold: 1.0%) OK
[14:45:01] Round 2
Rollout: v142 at 10% (inProgress)
crashes: 1.3% (threshold: 2.0%) OK
anr: 0.4% (threshold: 1.0%) OK
The loop stops automatically when the rollout reaches 100%, or you press Ctrl+C.
Configuring thresholds
Default thresholds are:
| Metric | Default |
|---|---|
| Crash rate | 2% |
| ANR rate | 1% |
| LMK rate | 3% |
| Slow start | 5% |
| Slow render | 10% |
Override any of them from the command line:
gpc watch --crash-threshold 0.015 --anr-threshold 0.005
Or set them once in .gpcrc.json so they apply to every gpc watch and gpc vitals call:
{
"vitals": {
"thresholds": {
"crashRate": 0.015,
"anrRate": 0.005,
"lmkRate": 0.03
}
}
}
Priority: CLI flags beat config, config beats defaults.
Watching more metrics
By default, gpc watch monitors crashes and ANR. Add more:
gpc watch --metrics crashes,anr,lmk,slowStarts,slowRender
Six metrics are available: crashes, anr, lmk, slowStarts, slowRender, errorCount.
Auto-halt on breach
This is where it gets useful. Instead of watching numbers scroll by, tell GPC to halt the rollout automatically if a threshold breaches:
gpc watch --on-breach halt
If the crash rate crosses 2%, GPC calls the Google Play API to halt the release. No human in the loop. The watch session logs it and exits.
You can combine actions:
gpc watch --on-breach notify,halt
This sends an OS notification AND halts the rollout.
Webhook integration
For teams using Slack, PagerDuty, or any webhook-based alerting:
gpc watch --on-breach webhook --webhook-url https://hooks.slack.com/services/XXX
GPC POSTs a JSON payload on breach:
{
"type": "breach",
"round": 3,
"timestamp": "2026-04-25T14:45:00.000Z",
"rollout": {
"track": "production",
"versionCode": "142",
"userFraction": 0.1,
"status": "inProgress"
},
"vitals": {
"crashes": { "value": 0.025, "threshold": 0.02, "breached": true },
"anr": { "value": 0.005, "threshold": 0.01, "breached": false }
},
"breaches": ["crashes"],
"halted": true
}
Combine all three for maximum coverage:
gpc watch --on-breach notify,halt,webhook --webhook-url https://hooks.slack.com/services/XXX
Set the webhook URL in config to avoid passing it every time:
{
"webhooks": {
"watch": "https://hooks.slack.com/services/XXX"
}
}
CI/CD integration
For automated pipelines, run a fixed number of rounds with JSON output:
gpc watch --rounds 3 --interval 300 --json
This outputs NDJSON (one JSON object per round), runs 3 polling cycles at 5-minute intervals, and exits with code 6 if any threshold was breached. Code 0 means clean.
In a GitHub Actions workflow:
- name: Monitor rollout vitals
run: gpc watch --rounds 3 --interval 300 --on-breach halt --json
env:
GPC_SERVICE_ACCOUNT: ${{ secrets.GPC_SERVICE_ACCOUNT }}
GPC_APP: com.example.app
Watching a specific track
Monitor a beta rollout instead of production:
gpc watch --track beta --crash-threshold 0.015
Beta rollouts often warrant tighter thresholds since you want to catch problems before they reach production users.
A note on data freshness
Google Play vitals data lags 24-48 hours behind real-time. Rollout status (version code, user fraction, track) is near real-time.
This means gpc watch is most useful for multi-day staged rollouts, which is exactly when you need it. You push to 1% on Monday, vitals data for that cohort is available by Wednesday, and you decide whether to ramp to 10%.
For the first few hours after a release, rollout status is the primary signal. Vitals data fills in as it becomes available.
Putting it together
A typical staged rollout workflow:
# Upload and release to 1%
gpc releases upload app.aab --track production
gpc releases rollout --fraction 0.01
# Watch with auto-halt and Slack alerts
gpc watch --on-breach notify,halt,webhook \
--webhook-url https://hooks.slack.com/services/XXX
# If vitals look good after 24-48h, bump to 10%
gpc releases rollout --fraction 0.10
# Watch again
gpc watch --on-breach notify,halt
# Ramp to 100%
gpc releases rollout --fraction 1.0
Or automate the entire flow with gpc train, which chains staged rollout steps with time gates and vitals gates.
Free to use. Code is on GitHub.
Top comments (0)