React Native · OTA Rollback · Safety Guide · 2026

Bad Update? Roll It Back Automatically

A bad OTA push can crash every device in your fleet. This guide covers crash-aware auto-rollback, manual CLI commands, rollback storm mitigation, and the telemetry you need to make the call.

Crash Detected
Native Exception
Launch Timeout
9:41
Stable Version v2.4.0 active
Reverting
OTA UPDATE v2.4.1
760 KB
Installing patch...
Reloading JS runtime
Rollback Complete
Failure Modes

When Should You Roll Back?

Not every bug warrants a rollback. These four failure modes should trigger an immediate rollback; waiting costs you users.

Crash on Launch

The app crashes within 10 seconds of applying a new OTA bundle. The user sees a white screen or the OS crash dialog. This is the most severe failure; every subsequent app launch crashes again.
Severity: Critical; auto-rollback required

JS Errors Above Threshold

The app doesn't crash, but unhandled JS exceptions spike above your baseline. A 3× increase in error rate within 15 minutes of deployment signals a broken update, even if the app stays running.
Severity: High; rollback if rate exceeds 3x baseline

Native Exception

An OTA update shouldn't touch native code, but a JS bundle that calls a renamed or removed native module will throw a native exception. These are harder to catch because they bypass JS error handlers.
Severity: Critical; native crashes require immediate rollback

User-Reported Regression

No crash, no error spike, but users report that a feature is broken, a screen is blank, or data isn't loading. These silent regressions slip past automated checks and require manual rollback judgment.
Severity: Medium; manual rollback after verification
Decision Tree

Should I Roll Back This Release?

Follow this decision tree when a release looks bad. Screenshot it, pin it in Slack, tape it to your monitor.

Start
New OTA release deployed
Is the app crashing on launch?
Yes
Immediate Auto-Rollback
Revert to last known-good bundle. No human decision needed.
ROLLBACK NOW
No
Check JS error rate
Compare error rate against pre-deploy baseline.
Error rate > 3x baseline?
Yes
Rollback within 15 minutes
Halt rollout. Rollback affected devices. Investigate root cause.
ROLLBACK
No
Check user reports & metrics
Monitor for 30 min. Check support tickets, cold start time, feature usage.
Were any issues flagged in metrics or reports?
Yes
Manual Rollback
Run CLI rollback. Notify stakeholders. Post-mortem within 24h.
CLI ROLLBACK
No
Continue Rollout
Promote to next rollout tier. Increase from 10% to 50% to 100%.
SHIP IT
Automatic Rollback

Crash-Aware Auto-Rollback

The best rollback is one that happens before your users file a ticket. Crash-aware rollback detects fatal failures and reverts the bundle on the next app launch. No human intervention required.

01
Mark Bundle as Pending

When a new OTA bundle is downloaded and ready to apply, the SDK marks it as PENDING in local storage. The previous known-good bundle hash is preserved as the fallback target.

02
Start Crash Timer on Launch

On the next app launch, the SDK starts a 10-second crash detection window. If the app survives this window without a fatal exception, the bundle status is promoted to CONFIRMED. The pending flag is then cleared.

03
Crash Detected: Revert Instantly

If the app crashes during the detection window, the SDK sees the PENDING flag on next launch and loads the previous known-good bundle instead. The bad bundle is quarantined and a rollback event is reported to the server.

AppsOnAir CodePush: Auto-Rollback Built In
AppsOnAir CodePush includes crash-aware auto-rollback out of the box. No configuration is needed; the SDK handles the pending/confirmed lifecycle, crash detection window (configurable from 5s to 30s), and automatic revert. Every rollback event is logged to your dashboard with the crash stack trace.
Works with both the old Bridge architecture and React Native Bridgeless mode (0.76+). The restart module adapts automatically.
Manual Rollback

CLI Commands for Manual Rollback

When auto-rollback doesn't trigger (silent regressions, performance degradation, user complaints), you need manual control. These CLI commands give you full rollback power.

Rollback to Previous Release
terminal
# Roll back production to the previous release
appsonair-codepush rollback <appName>

# Verify the rollback
appsonair-codepush deployment history <appName>
Reverts all devices to the last known-good release. Devices pick up the rollback on their next sync check.
Rollback to Specific Version
terminal
# Target a specific release label
appsonair-codepush rollback <appName> --targetRelease v2.3.8
Skip multiple bad releases and target a known stable version. Essential during migration cutover from another OTA provider.

Rollback that protects every device

Built-in crash detection. Automatic revert. Zero manual intervention for critical failures.

<10s
Auto-Rollback
100%
Signed Bundles
No
Config Required
The Rollback Storm

100k Devices Roll Back at Once

A rollback storm happens when a bad update reaches your entire user base and every device tries to download the previous bundle simultaneously. Your CDN gets hit by a thundering herd. Here's how to survive it.

The Math of a Rollback Storm
100,000 devices × 2MB bundle = 200GB of sudden CDN traffic. If your CDN can't auto-scale, devices experience timeouts, retry requests, and amplify the load. Some devices end up stuck on the bad bundle because the rollback download fails.
Jittered Rollback Delays

Add a random delay (0–60s) before each device downloads the rollback bundle. This spreads the thundering herd across a minute instead of creating a single traffic spike.

Auto-Scaling CDN

Your bundle hosting must handle burst traffic. Static file hosts with fixed bandwidth caps will buckle under load. Use a CDN with edge caching and auto-scaling, or let AppsOnAir's global edge network handle it.

Local Bundle Cache

Keep the previous bundle cached on the device. During a rollback, the SDK loads the local cache instead of re-downloading the bundle: zero network traffic, instant revert. AppsOnAir CodePush retains the last two bundles by default.

AppsOnAir CodePush: Storm-Proof by Design
AppsOnAir CodePush uses all three strategies automatically: jittered rollback delays, a global edge CDN with auto-scaling across 200+ PoPs, and local bundle caching. Even if 100k devices roll back simultaneously, your infrastructure stays healthy. No configuration is needed.
Rollback Prevention

Percentage-Based Rollouts Don't Ship to Everyone

The best rollback is the one you never need. Stage your releases and catch problems when they affect 5,000 users, not 500,000.

01
Canary: Internal + Beta Users

Push to 5% of your user base, ideally internal team members and opted-in beta users. Monitor crash rates, JS errors, and cold-start times for 30 minutes.

02
Early Adopters: Broader Validation

If the canary looks clean, promote to 25%. This catches device-specific issues: older phones, different OS versions, and lower-bandwidth networks. Hold for 2 hours.

03
General Availability: Full Fleet

Metrics green at 25%? Ship to everyone. If anything goes wrong at this stage, auto-rollback handles it. Staged rollouts mean you almost never get here with a bad build.

Set Rollout Percentage
terminal
# Start with 5% canary
appsonair-codepush <appName> --rollout 5

# Promote to 25% after validation
appsonair-codepush <appName> --rollout 25

# Ship to 100%
appsonair-codepush <appName> --rollout 100
  
Version Pinning

Lock High-Stakes Updates in Place

Some updates can't be rolled back. Payment flow changes, auth migrations, and database schema updates; pin these versions so no OTA update overwrites them until you're ready.

When to Pin
During audit periods or compliance freezes
After a payment gateway migration
When native + JS versions must stay in sync
During A/B test measurement windows
For enterprise clients on locked firmware
Pinning Risks
Pinned devices miss security patches
Version drift across your user base
Forgetting to unpin after the freeze window
Pinned devices can't auto-rollback to newer fixes
Set pin expiry dates to avoid stale locks
Observability

The Telemetry You Need to Decide

You can't make a rollback decision without data. These six signals are the minimum telemetry you need to run OTA updates safely.

Crash Rate per Bundle

Crash rate segmented by bundle version. Compare the new release's crash rate against the previous version's baseline within the first 30 minutes.

JS Error Rate + Traces

Unhandled JS exception count per minute, with full stack traces. A 3× spike over baseline within 15 minutes warrants investigation.

Update Adoption Curve

How quickly devices are picking up the new bundle. A stalled adoption curve means devices are failing to download or apply the update.

Cold Start Time Delta

Compare cold-start time before and after the update. A 500ms+ regression signals a bundle-size or initialization problem worth rolling back.

Rollback Event Count

How many devices have auto-rolled back. Even a small percentage of auto-rollbacks means some users are experiencing crashes that aggregate metrics might hide.

User Reports + Support Tickets

Automated signals miss UX regressions. Correlate support ticket volume with OTA deployment timestamps to catch silent failures that humans notice but machines don't.

AppsOnAir CodePush: Full Observability Dashboard
AppsOnAir CodePush provides all six signals out of the box: real-time crash rates per bundle version, JS error aggregation with source-mapped stack traces, adoption curves, cold-start benchmarks, rollback event tracking, and configurable alert thresholds.
AppsOnAir CodePush

Every Rollback Scenario Handled

Here's how AppsOnAir CodePush handles each rollback scenario: no custom code, no infrastructure setup, no manual configuration.

Scenario
AppsOnAir CodePush
DIY / Manual
Crash on launch
Built-in auto + manual rollback
Custom crash handler + manual revert logic
Rollback storm
Global edge CDN + jitter + local cache
Scale CDN yourself + implement jitter
Staged rollout
CLI + dashboard percentage controls
Feature flags or custom server logic
Version pinning
Server-side pin with expiry dates
Hard-code version checks in app
Bridgeless mode rollback
Bridgeless-aware restart built in
Custom native restart module required
Observability
Full dashboard with alerts included
Integrate Sentry + Datadog + custom scripts
FAQ

Got Questions? We've Got Answers

What triggers an automatic OTA rollback?

How do I manually roll back an OTA update?

What is a rollback storm and how do I prevent it?

Should I use percentage-based rollouts?

What telemetry do I need for rollback decisions?

Can I pin a specific OTA version to prevent updates?

Does rollback work differently in Bridgeless mode?