skip to content

Staged Rollout & Revert

EAS Update can roll an update out to a share of users, revert it, or roll back to an earlier update or the embedded bundle; code signing proves origin. Interviewers ask how bad updates are undone.

part ofExpo (React Native)overview, primer and where to startread it →
on this pageshow

explore

questions

5

In EAS Update, how do you publish an update to 10% of users, then widen or finish that rollout?

level: middleimportance: must knowfreq 45%

answer

  1. one flag on the publish command
  2. eas update --rollout-percentage 10
  3. update:edit can only go up
  4. finish at 100 or revert
  5. one rollout per branch at a time

basics

~20 s

Publish with eas update --rollout-percentage 10, so only that share of devices gets the update and the rest keep the previous one. Raise it with eas update:edit, then end it by setting 100 or by running eas update:revert-update-rollout.

solid answer

~40 s

EAS Update has **per-update rollouts**. You add `--rollout-percentage 10` to the normal `eas update` command, and only that share of devices on the branch receives the new update; everyone else keeps being served the previous latest update. To widen it you run `eas update:edit` and set a higher percentage; the CLI refuses a lower one. A rollout ends one of two ways: set it to 100 to release fully, or run `eas update:revert-update-rollout` to undo it. Two constraints matter in practice: only one update can be rolling out on a branch at a time, and while it is in progress you cannot publish another update for the same runtime version until you end it. `eas update:list` and `eas update:view` show the current percentage.

code

bash · 11 lines
bash
# Start: 10% of devices on the production branch get the update
eas update --channel production --environment production \
  --message "Fix share button crash" --rollout-percentage 10

# Widen: the new value may not be lower than the current one
eas update:edit "$GROUP_ID" --rollout-percentage 50

# End: release fully...
eas update:edit "$GROUP_ID" --rollout-percentage 100
# ...or undo and republish the previous update
eas update:revert-update-rollout --group "$GROUP_ID"

go deeper

for a junior

Recall the flag, eas update --rollout-percentage, and that the rest of the devices keep getting the previous update.

for a middle

Explain the lifecycle: update:edit only upwards, finish at 100 or revert, and why a new publish is blocked until the rollout ends.

for a senior

Plan a release around the rules: when a hotfix forces you to revert first, and when a branch-based rollout suits a train of updates better.

for a principal

Decide the step sizes and who may widen a rollout, tying EAS's mechanics to your own health signals rather than to the calendar.

## Why roll out an over-the-air update gradually **EAS Update** delivers JavaScript and assets to builds without a store release, which also means a mistake reaches every compatible device on the next launch. A **rollout** limits that blast radius: the update goes to a percentage of devices first, and you widen it only once it behaves. EAS offers two mechanisms, and the everyday one is the **per-update rollout**. ## Starting a per-update rollout Add one flag to the command you already use: ```bash eas update --channel production --environment production \ --message "Fix share button crash" --rollout-percentage 10 ``` - `--rollout-percentage` takes an integer from 1 to 100 and defaults to 100 when omitted. - Devices in the rollout are offered the new update; devices outside it are served the **previous latest update** on the branch. - When the branch already had an update, the CLI prints an Android and an iOS rollout line with the percentage and the **base update ID**: the control update that devices outside the rollout keep running. (On Expo SDK 55 and later, `eas update` also asks for `--environment` outside CI, naming which EAS environment's variables the publish uses.) ## Progressing and ending it 1. **Widen** with `eas update:edit`, choosing the update group (or passing its ID) and a new `--rollout-percentage`. The CLI only accepts a value that is not lower than the current one; the interactive prompt demands a strictly higher one. 2. **Finish** by editing it to 100: the update becomes the branch's latest for everyone. 3. **Undo** with `eas update:revert-update-rollout`, which deletes the rollout update group and republishes the control update so every device converges on the previous state. If the branch had no earlier update, it publishes a **roll back to embedded** update instead. There is no "lower it to 0" path: backing out is always a revert. ## Rules that shape the workflow | Rule | Consequence | |---|---| | One rollout per branch at a time | You cannot stage two updates side by side on the same branch | | A rollout must end before the next publish for that runtime version | A hotfix during a 10% rollout means finishing or reverting first | | A rollout can start on an empty branch | Reverting it creates a roll-back-to-embedded update | | `update:edit` only works on rollout groups | Editing a normal update's percentage fails | The second rule surprises teams most: it exists so a new publish cannot silently clobber an in-flight rollout. ## Watching a rollout while it runs A rollout is only as good as the signal you widen it on. `eas update:list` and `eas update:view` show each group's current percentage, and the update's details page in the EAS dashboard shows how many devices ran it and how many installs failed, which is the first place a crashing update shows up. A typical cadence looks like this: 1. Publish at a small percentage and wait long enough for real sessions (hours, not minutes, for most apps). 2. Compare failed installs and your own crash numbers for the new update against the control update. 3. Widen in steps with `eas update:edit`, or revert at the first clear regression. 4. Finish at 100 so the branch is free for the next publish. The step sizes and waiting times are a team decision; EAS only enforces the mechanics. ## Branch-based rollouts, briefly The other mechanism, `eas channel:rollout`, moves a percentage of a **channel's** traffic to a different **branch** (a stream of updates) rather than to one update. It has `create`, `edit`, `end` and `view` actions; ending offers `republish-and-revert` (copy the new branch's latest update back to the old branch and point everyone there) or `revert`. While it runs, `eas update --channel` is refused because the CLI cannot tell which branch you mean, so you publish with `--branch`. Most teams start with per-update rollouts and reach for branch-based ones only when several updates must travel together. ## What the percentage does not do - It does not measure health for you: widening is a human (or pipeline) decision made from your own crash and adoption numbers. - It does not change native code: every device in the rollout still needs a build with a matching runtime version. - It does not replace testing: a 10% rollout of a crashing update still crashes for 10% of your users.

  • A teammate wants to publish an unrelated fix while your update sits at 10%. What happens?
    EAS blocks a new publish for the same runtime version on that branch until the rollout ends, so it cannot overwrite the rollout. You either finish it by editing to 100 or revert it with `eas update:revert-update-rollout`, then publish the fix, possibly as a new rollout.
  • When would you choose eas channel:rollout over a per-update rollout?
    When a set of updates must move together: a branch-based rollout sends a percentage of a channel's devices to a different branch, and every update published to that branch follows. You end it with `republish-and-revert` if the branch is good or `revert` to discard it. For a single update, `--rollout-percentage` is simpler.

A restaurant trying a new recipe on a few tables before printing it on every menu: you can put it on more tables later, and if it goes wrong you go back to the old recipe, but you cannot un-serve the plates already out.

saying these in an interview costs you the question

  • Thinks update:edit can lower a rollout to zero to stop it
  • Believes two updates can roll out on the same branch at once
  • Expects to publish a hotfix on top of an in-progress rollout
  • Assumes a rollout percentage also gates native code changes
  • Confuses --rollout-percentage with eas channel:rollout's branch split
open as a page

What does eas update:rollback do in EAS Update, and when does it roll back to the embedded update instead of a published one?

level: middleimportance: must knowfreq 46%

basics

~20 s

eas update:rollback undoes the latest update on a branch by publishing again: it republishes the update group before it, or, when none exists for that branch and runtime version, publishes a roll-back-to-embedded directive that returns clients to the bundle inside their binary.

open as a page

An EAS Update at a 10% rollout is crashing for some users; how do you revert it, and what happens to devices that already downloaded it?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Run eas update:revert-update-rollout: it deletes the rollout group and republishes the control update the other 90% run. Devices holding the bad update pick up that newer copy on their next check; if the branch had no earlier update, the revert publishes a roll back to embedded instead.

open as a page

As the lead of a team adopting EAS Update, what would you allow to ship over the air, and which EAS guardrails would you require?

level: principalimportance: should knowfreq 28%

basics

~20 s

Allow JavaScript and asset fixes and small flag-guarded features within the current runtime version; send native and large product changes through store builds. Require per-update rollouts, a rehearsed revert and rollback, code signing where tampering matters, and traceable publishes.

open as a page

How does EAS Update code signing prove an update came from you, and why does adding or rotating its certificate need a new runtime version?

level: seniorimportance: nice to knowfreq 20%

basics

~20 s

You generate a key pair and certificate with npx expo-updates codesigning:generate, embed the certificate in builds via updates.codeSigningCertificate, and sign each update locally with the private key; expo-updates verifies the signature before applying and rejects a missing or invalid one.

open as a page