Staged Rollouts for React Native: Deploy with Confidence
Learn how to implement staged rollouts for React Native OTA updates. Deploy to 1% of users first, monitor, then gradually expand to 100%.
Introduction: Why 100% Rollouts Are Risky
Picture this: You've tested your update, everything looks good, and you push it to all 500,000 users at once. Five minutes later, your error tracking lights up — there's a crash on Android 12 devices with Samsung's custom ROM. You just broke the app for 80,000 users.
This scenario is preventable. Staged rollouts let you deploy to a small percentage of users first, verify everything works, and then gradually expand to your entire user base.
It's the same strategy used by Google, Facebook, Netflix, and every company that deploys at scale. And with SwiftPatch, it's built right into the platform.
What Are Staged Rollouts?
A staged rollout (also called a phased release, gradual rollout, or canary deployment) is a deployment strategy where you release an update to a small percentage of users first, then gradually increase that percentage over time.
Staged Rollout Timeline:
Day 1, Hour 0: ██░░░░░░░░░░░░░░░░░░ 1% of users
Day 1, Hour 4: ████░░░░░░░░░░░░░░░░ 10% of users
Day 1, Hour 12: ██████████░░░░░░░░░░ 50% of users
Day 2, Hour 0: ████████████████████ 100% of users
At each stage, you monitor key health metrics. If something goes wrong, you halt the rollout or roll back — affecting only the small percentage of users who received the update.
The Standard Rollout Strategy
The most common staged rollout pattern follows four phases:
Phase 1: Canary (1%)
swiftpatch release --platform all --rollout 1 --description "v2.5.1: Checkout flow improvements"
Deploy to 1% of your users. This is your canary group — they're the first to receive the update.
Duration: 1-2 hours
- Crash rate (should not increase)
- JavaScript error rate
- API error rates from updated endpoints
- Console logs and Sentry/Bugsnag reports
Phase 2: Early Adopters (10%)
swiftpatch promote --rollout 10
If canary looks healthy, expand to 10%. This gives you a statistically meaningful sample to validate performance.
Duration: 4-6 hours
- All Phase 1 metrics
- User engagement metrics (session length, screen views)
- Conversion rates for affected flows
- Performance metrics (startup time, frame rate)
Phase 3: Majority (50%)
swiftpatch promote --rollout 50
Half your users now have the update. At this scale, most device/OS combinations are covered.
Duration: 12-24 hours
- All Phase 2 metrics
- Support ticket volume
- App store reviews sentiment
- Edge cases on less common devices
Phase 4: Full Release (100%)
swiftpatch promote --rollout 100
Everything looks good. Ship it to everyone.
Post-release monitoring: Continue monitoring for 48 hours after full release.
Canary Deployments Explained
A canary deployment is the first phase of a staged rollout. The term comes from the practice of coal miners bringing canaries into mines — if the canary stopped singing, it meant dangerous gas levels, and miners would evacuate.
In software, your 1% canary users are the early warning system. If the update causes problems, you detect it before it affects your entire user base.
How SwiftPatch Selects Canary Users
SwiftPatch uses a deterministic hashing algorithm to select which users are in each rollout percentage:
hash(device_id) % 100 < rollout_percentage → receives update
- The same user always gets the update at the same rollout percentage
- Users in the 1% group are always included in the 10% group, the 50% group, etc.
- Selection is uniform across devices and platforms
A/B Comparison
Because canary users are deterministically selected, you can compare metrics between the canary group (updated) and the control group (not updated):
Canary group (1% - updated):
Crash rate: 0.3%
Avg session length: 4.2 min
Control group (99% - not updated):
Crash rate: 0.3%
Avg session length: 4.1 min
Status: ✅ No regression detected
Monitoring During Staged Rollouts
Key Metrics to Watch
Critical Metrics (block rollout if degraded):
- Crash rate
- ANR (App Not Responding) rate
- JavaScript fatal errors
- App startup failures
Important Metrics (investigate if degraded):
- Non-fatal error rate
- API error rates
- Performance (startup time, FPS)
- Memory usage
Business Metrics (watch for trends):
- Session length
- Conversion rates
- Feature adoption
- User retention
Setting Up Monitoring
# Configure alerts for rollout monitoring
swiftpatch alerts create \
--metric crash_rate \
--threshold 0.5 \
--comparison increase_percent \
--channel slack:#mobile-alerts
swiftpatch alerts create \
--metric error_rate \
--threshold 2.0 \
--comparison increase_percent \
--channel email:mobile-team@company.com
Real-Time Dashboard
SwiftPatch's dashboard shows real-time rollout metrics:
Deployment: dep_abc123
Status: Rolling out (10%)
Platform: all
Created: 2 hours ago
Metrics (updated vs baseline):
Crash rate: 0.31% vs 0.30% (stable ✅)
Error rate: 1.2% vs 1.1% (stable ✅)
Startup time: 1.8s vs 1.7s (stable ✅)
Adoption: 9.8% of eligible users
When to Pause, Rollback, or Expand
Decision Framework
After each rollout phase, ask:
1. Has crash rate increased?
YES → Rollback immediately
NO → Continue
2. Has error rate increased significantly (>2%)?
YES → Pause and investigate
NO → Continue
3. Are there user-reported issues?
YES → Pause and investigate
NO → Continue
4. Are performance metrics stable?
YES → Proceed to next phase
NO → Pause and investigate
All clear? → Expand to next phase
Pausing a Rollout
# Pause at current percentage (no new users get the update)
swiftpatch pause --deployment dep_abc123
Rolling Back
# Full rollback (all users revert to previous version)
swiftpatch rollback --deployment dep_abc123
# Users who already received the update will get the rollback
# on their next app launch
Resuming After Pause
# Resume rollout at the current percentage
swiftpatch resume --deployment dep_abc123
# Or promote to a higher percentage
swiftpatch promote --rollout 50
Automated vs. Manual Rollout Expansion
Manual Expansion
Best for critical updates or teams new to staged rollouts:
# Each promotion requires explicit CLI command
swiftpatch release --platform all --rollout 1
# ... human reviews metrics ...
swiftpatch promote --rollout 10
# ... human reviews metrics ...
swiftpatch promote --rollout 50
# ... human reviews metrics ...
swiftpatch promote --rollout 100
Automated Expansion
Best for mature teams with good monitoring:
swiftpatch release --platform all \
--rollout 1 \
--auto-expand \
--expand-schedule "1:2h,10:6h,50:24h,100" \
--halt-on-crash-increase 0.5 \
--halt-on-error-increase 2.0
- Deploys to 1% of users
- After 2 hours, if metrics are healthy, expands to 10%
- After 6 hours at 10%, expands to 50%
- After 24 hours at 50%, expands to 100%
- Automatically halts if crash rate increases by 0.5% or error rate by 2.0%
Hybrid Approach
Many teams use automated expansion with manual gates:
swiftpatch release --platform all \
--rollout 1 \
--auto-expand \
--expand-schedule "1:2h,10:6h,50" \
--require-approval-at 50
This automates expansion from 1% to 10%, but requires manual approval before going to 50%.
SwiftPatch Staged Rollout Implementation
CLI Commands Reference
# Create a staged release
swiftpatch release --platform <ios|android|all> --rollout <percentage>
# Promote to higher percentage
swiftpatch promote --rollout <percentage>
# Pause rollout
swiftpatch pause
# Resume rollout
swiftpatch resume
# Rollback
swiftpatch rollback
# Check status
swiftpatch status
# View rollout history
swiftpatch rollout-history --deployment dep_abc123
Configuration File
# swiftpatch.yaml
rollout:
default_strategy: staged
phases:
- percentage: 1
duration: 2h
auto_expand: true
- percentage: 10
duration: 6h
auto_expand: true
- percentage: 50
duration: 24h
auto_expand: false # Require manual approval
- percentage: 100
halt_conditions:
crash_rate_increase: 0.5%
error_rate_increase: 2.0%
startup_time_increase: 20%
alerts:
- channel: slack
webhook: ${SLACK_WEBHOOK}
- channel: email
recipients:
- mobile-team@company.com
CI/CD Integration for Staged Rollouts
GitHub Actions
# .github/workflows/staged-deploy.yml
name: Staged OTA Deployment
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
deploy-canary:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Deploy Canary (1%)
run: |
npx swiftpatch release \
--platform all \
--rollout 1 \
--sign \
--private-key ${{ secrets.SWIFTPATCH_PRIVATE_KEY }}
env:
SWIFTPATCH_ACCESS_KEY: ${{ secrets.SWIFTPATCH_ACCESS_KEY }}
expand-rollout:
needs: deploy-canary
runs-on: ubuntu-latest
environment:
name: production-expand
steps:
- name: Expand to 100%
run: npx swiftpatch promote --rollout 100
env:
SWIFTPATCH_ACCESS_KEY: ${{ secrets.SWIFTPATCH_ACCESS_KEY }}
The production-expand environment can be configured in GitHub with required reviewers, forcing a human approval step before the rollout expands.
Real-World Examples
Example 1: E-Commerce App
An e-commerce app with 2 million users deploys a checkout flow update:
Day 1, 9:00 AM: Deploy to 1% (20,000 users)
Day 1, 11:00 AM: Metrics stable → expand to 10%
Day 1, 5:00 PM: Metrics stable → expand to 50%
Day 2, 9:00 AM: Metrics stable → expand to 100%
Result: Zero incidents, smooth rollout over 24 hours
Example 2: Banking App (Conservative)
A banking app with 500,000 users deploys a critical security patch:
Day 1, 10:00 AM: Deploy to 0.5% (2,500 users)
Day 1, 2:00 PM: Internal QA verifies → expand to 5%
Day 2, 10:00 AM: All metrics green → expand to 25%
Day 3, 10:00 AM: Compliance review → expand to 100%
Result: Extra-cautious rollout over 3 days, zero issues
Example 3: Emergency Hotfix
A social media app discovers a critical crash affecting all users:
Hour 0: Deploy fix to 10% (skip 1% for speed)
Hour 1: Crash rate drops from 5% to 0.3% → expand to 50%
Hour 2: Confirmed fixed → expand to 100%
Result: Critical fix deployed to all users in 2 hours
Conclusion
Staged rollouts are the difference between deploying with confidence and deploying with fear. By releasing to a small percentage of users first, you catch issues before they become widespread problems.
- One command to set rollout percentage
- Automatic expansion with health monitoring
- Instant rollback if something goes wrong
- Real-time metrics to inform decisions
Stop deploying to 100% and hoping for the best. Deploy to 1%, know it's good, and then expand with confidence.
Ready to ship updates faster?
Get started with SwiftPatch for free. No credit card required.
Join WaitlistRelated Articles
Expo EAS Update Pricing: Cost, Bandwidth & What It Really Costs at Scale
Expo EAS Update feels cheap when you're starting out. Then your app grows. Here's how Expo actually bills for EAS Update, why costs grow faster than you expect, and what happens when you're shipping frequent releases to real users.
ComparisonExpo EAS Update Alternative — Best Expo Updates Replacement with Patch Updates
Expo EAS Update works well inside the Expo ecosystem. But as apps scale, teams need patch updates, rollback, internal testing, bare React Native support, and on-premise hosting. Here's how SwiftPatch compares.
GuidePatch Updates: The Modern CodePush Alternative
Microsoft CodePush is deprecated. Learn how to migrate to SwiftPatch, the modern OTA update platform for React Native with 98% smaller patches, automatic rollback, and enterprise security.