Loading... Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?
Controlled rollouts in React Native: how to push OTA updates without breaking production

Controlled Rollouts in React Native: How to Push OTA Updates Without Breaking Production

Jun 5, 2026 - 13 min read

This article is written by Karl Suhajda

The ability to push an update directly to your users’ devices without App Store review, without delay, without any action required from the user, is one of the most powerful capabilities available to a React Native team. Over-the-air (OTA) updates change how fast you can respond to bugs, iterate on features, and ship improvements.

But that power cuts both ways.

A bad OTA update reaching 100% of your users at once is considerably worse than a bad store release. A store release takes days to go live, which means you have time to catch problems before broad distribution. An OTA push can reach your entire user base within hours of deployment. If something is wrong, the blast radius is immediate and total.

Controlled rollouts are the practice that makes OTA updates genuinely safe at scale. Rather than pushing to everyone at once, you release to a small percentage of your user base first, monitor the results carefully, and expand only when you have confidence the update is stable. A problem that affects 5% of users is a recoverable incident. The same problem at 100% is a crisis.

This post walks through the full controlled rollout process, how to structure your deployment channels, how to execute a staged rollout step by step, what to watch in your analytics, and how to build the team processes that make every OTA push predictable rather than stressful.

Ready to set up controlled rollouts for your React Native app?

Codemagic CodePush gives you deployment channels, rollout controls, and per-channel analytics, all managed from a web dashboard, no CLI required.

Start your free trial at codemagic.io/codepush

Why shipping to 100% at once is the fastest way to create a crisis

The temptation to push directly to your full production audience is understandable. Your fix is validated. Your tests passed. You have confidence in the change. Why add friction?

The answer is that production environments surface problems that testing cannot. Your test suite runs on a controlled set of devices and configurations. Your staging environment, however well-maintained, is not production. Real users bring real variability, unusual device models, old OS versions, low-memory conditions, unexpected network states, combinations of app settings your tests never touched.

The history of mobile app incidents is full of bugs that passed every test and broke in production. The difference between a team that handles this well and a team that does not is not whether they encounter these bugs. It is whether they have the infrastructure to catch them at limited exposure before they become visible at scale.

Controlled rollouts are that infrastructure. They do not eliminate risk. They contain it.

Deployment channels: the foundation of controlled rollouts

Before you can execute a staged rollout, you need deployment channels configured. A deployment channel is a named target environment, a separate bucket into which you push updates, with its own user base, its own version history, and its own analytics.

At minimum you need two channels. Three is better.

Staging

Your staging channel is accessible only to your internal team, developers, QA engineers, product managers. Every update goes to staging first, without exception. Staging is where you verify that the update delivers correctly, that the fix works as expected, and that nothing unexpected has broken.

The key requirement for staging is that it mirrors production as closely as possible. Same API endpoints where feasible. Same feature flags. Same data structures. The closer staging is to production, the more confidence you can have when promoting an update from staging to the next channel.

Beta

A beta channel sits between staging and production. It reaches a defined subset of real users, typically people who have opted into early access, internal testers outside the core development team, or a small percentage of your production audience. Beta is your first real-world signal on an update.

Some teams skip the beta channel for routine updates and use it selectively for larger changes. That is a reasonable approach. The important thing is that the option exists and that your team knows when to use it.

Production

Your production channel is where your full user base receives updates. Nothing should reach production without having been validated in staging, and ideally validated in beta for any change with meaningful scope or risk.

The staged rollout process: step by step

With channels in place, a controlled rollout follows a consistent pattern. The specific percentages and timings can be adjusted for your context, a critical hotfix might move through stages faster than a routine update, but the structure remains the same.

Step 1: Push to staging

Deploy the update to your staging channel. Your internal team, developers, QA, anyone with the app installed on a staging build, receives it on their next app launch.

What you are validating:

  • The update delivers correctly, the bundle installs without errors
  • The fix or change works as expected in a near-production environment
  • Nothing unexpected has regressed in adjacent functionality
  • The rollback works, trigger a rollback via the CLI and confirm the app reverts cleanly to the previous bundle

That last point deserves emphasis. Test your rollback in staging every time, not just when you first set things up. Rollback procedures can break, a dependency change, a configuration update, an infrastructure modification, and you want to discover that in staging, not mid-incident in production.

Step 2: Promote to beta (if using a beta channel)

Once staging is validated, promote the update to your beta channel. This is your first signal from real device conditions and real usage patterns.

Monitor beta for a meaningful period before proceeding. The appropriate window depends on your update frequency and user base size. For routine updates, a few hours may be sufficient. For significant changes, 24 hours gives you a reasonable confidence window.

Step 3: Push to production at 5 to 10%

Push the update to production, but configure the rollout to reach only 5 to 10% of your production user base initially. This is your canary release, a small group that represents real production conditions without risking full exposure.

The 5 to 10% threshold is deliberately conservative. The goal is not to get the update to users quickly at this stage. It is to validate that nothing unexpected happens in production before you commit to full rollout.

See the full feature set and analytics dashboard in action.

Talk to the Codemagic team at codemagic.io/contact-sales

Step 4: Monitor the canary release

After the initial push, watch your metrics carefully before doing anything else. You are looking for signals that distinguish a clean deployment from a problematic one.

  • Install rate: is the update being picked up at the expected pace? A lower-than-expected install rate can indicate a delivery problem.
  • Crash rate: has the crash rate changed relative to your pre-update baseline? Even a modest increase at 5% is significant, it projects to a much larger impact at 100%.
  • Error logs: are new errors appearing that were not present before the push? Errors that only appear post-deployment are a signal worth investigating before expanding the rollout.
  • Version distribution: what percentage of your active users is now on the new bundle? Is this tracking as expected given your rollout percentage?

Give the canary release a monitoring window appropriate to your update volume. If your app has high daily active usage, you may have sufficient signal within an hour or two. If usage is lower or more concentrated in certain time zones, wait for a full usage cycle before drawing conclusions.

If anything looks unusual, a crash rate increase, an unexpected error pattern, an install rate anomaly, pause the rollout and investigate before expanding. This is the entire point of the canary stage.

Step 5: Expand to 25%, then 50%

If the canary metrics are clean, expand to 25% of your production user base. Repeat the monitoring window. Then expand to 50%.

The intermediate steps serve two purposes. First, they give you additional confidence at increasing scale, a problem that did not appear at 5% might appear at 25% on a different distribution of device types. Second, they keep the rollback scope manageable. If something goes wrong at 25%, you are rolling back 25% of users rather than 100%.

For low-risk updates, a copy change or a minor UI tweak, you may choose to move through these stages faster. For higher-risk changes, API integration updates, new feature flags, significant logic changes, take the full monitoring window at each stage.

Step 6: Expand to 100%

Once you have clean metrics through the intermediate stages, expand to 100%. The remaining users receive the update on their next app launch.

Continue monitoring for 24 to 48 hours after full rollout. Production at 100% can still surface edge cases that did not appear at partial rollout percentages. Keep the previous stable bundle available for rollback throughout this period.

Step 7: Document and close

Once you are confident the update is stable at full rollout, close the deployment with a brief record of what was pushed, when, what the rollout progression looked like, and any signals that appeared along the way.

This documentation compounds in value over time. Teams that maintain deployment records develop an accurate picture of their update history, understand their rollback frequency, and identify patterns in which types of changes carry more risk than others.

Setting up rollback before you need it

Rollback is not a contingency to configure when something goes wrong. It is a capability that must be set up, tested, and documented before any production push.

A rollback reverts your production deployment to the previous stable bundle. Users who have already received the problematic update get the previous version on their next app launch. Users who have not yet received the update never see it.

Three things your rollback process must have:

It must be tested. Trigger a rollback in staging regularly, not just at initial setup. Treat it as part of your deployment validation checklist, the same way you test that the update itself delivers correctly.

It must be documented. Who has CLI access to trigger a rollback? What are the exact commands? Where is the runbook? This information needs to be in a place that is accessible during an incident, not stored in someone’s memory.

It must be fast. When a rollback is needed, it is usually needed immediately. The time to learn your rollback CLI commands is not when your error rate is climbing. Run through the commands in staging until the steps are instinctive and make sure the runbook is somewhere the whole team can access it.

Codemagic CodePush rollbacks are triggered via the CLI. This means the person responsible for executing a rollback needs to be comfortable with the command line and have the necessary access credentials ready before an incident occurs. Documenting the exact commands and ensuring the right people have CLI access set up in advance is not optional. It is part of your deployment readiness.

Analytics: what to watch and when to act

The Codemagic CodePush dashboard provides per-channel metrics across every active deployment. Understanding what you are looking at and what thresholds should trigger action is as important as having the data.

Downloads vs. installs

A download means the bundle has been fetched from the update server. An install means it has been applied to a device and the app has launched with the new bundle. Both metrics matter.

A high download count with a low install count can indicate users are downloading but not launching the app, normal for some update configurations, or that something is preventing the bundle from being applied correctly.

Baseline comparison

Before any production push, note your current baseline metrics: crash rate, error rate, key user flows. Post-deployment, compare against this baseline. An update that improves stability should show a declining crash rate. An update that introduces a problem will show an increase. Without a baseline, you are flying blind.

The team process behind safe rollouts

The technical infrastructure for controlled rollouts is only half of the picture. The other half is the team process that ensures the infrastructure gets used correctly and consistently.

Define who can push to production. Not everyone who can push to staging should have production deploy access. Define this explicitly, document it, and review it when team composition changes.

Require staging validation before any production push. Make this a rule, not a guideline. The pressure to skip staging during a critical incident is precisely when skipping staging is most dangerous.

Create a deployment checklist. A short written checklist, confirming staging validation, rollback tested, monitoring baseline noted, and rollout percentage set correctly, takes two minutes to complete and prevents the kind of oversight that causes incidents.

Define escalation thresholds. What crash rate increase triggers a rollback? What error pattern requires a pause? Decide this before the push, not during it. Teams that define thresholds in advance make faster, cleaner decisions under pressure.

Review deployments after the fact. A brief post-deployment review, even just five minutes, asks whether the rollout went as expected, whether the metrics told a clear story, and whether anything should change about the process next time. This is how deployment practices improve.

Frequently Asked Questions

What is a controlled rollout in React Native OTA updates?

A controlled rollout means pushing an OTA update to a small percentage of your production user base first, typically 5 to 10%, monitoring metrics like crash rate and install rate, then expanding to larger percentages and eventually 100% only when you are confident the update is stable. This limits the blast radius of any problem that surfaces in production.

What percentage should I start my OTA rollout at?

5 to 10% is the recommended starting point for most React Native teams. This gives you meaningful signal from real production conditions while limiting exposure if something goes wrong. For low-risk changes like copy updates, you may move through stages faster. For significant logic changes or API integration updates, stay at each percentage for a full monitoring window before expanding.

What should I monitor after pushing an OTA update?

Monitor install rate (is the update being picked up as expected?), crash rate (has it changed relative to your pre-update baseline?), error logs (are new errors appearing post-deployment?), and version distribution (what percentage of active users is now on the new bundle?). Compare against your pre-deployment baseline rather than relying on absolute numbers alone.

How do deployment channels work in Codemagic CodePush?

Deployment channels are separate named environments, staging, beta, and production, each with its own user base, version history, and analytics. Every update goes to staging first for internal validation, optionally to a beta channel for early real-user testing, then to production with a staged percentage rollout. Channels are managed from the Codemagic CodePush dashboard.

How quickly can I roll back an OTA update that causes problems?

Rollbacks in Codemagic CodePush are triggered via the CLI, reverting production users to the previous stable bundle. Users who have already received the problematic update get the previous version on their next app launch. Users who have not received the update yet never see it. CLI access and the exact rollback commands must be documented and tested in staging before any production push.

Build a React Native deployment process you can trust.

Codemagic CodePush, hosted OTA updates with deployment channels, rollout controls, and analytics built in. Free trial available. No infrastructure required.

Get started at codemagic.io/codepush

Latest articles

Show more posts