A mobile app update is released by bumping the build number of the new version, uploading it to the store, passing review and opening it to users gradually. The difference from the first launch is that real users are now in the field, and if a broken version reaches everyone at once there is no taking it back — neither store offers a rollback button. They only let you halt distribution and ship a fixed version with a higher number. So the core of the update process is not speed but a controlled rollout.
This article is not about getting the app into the store for the first time; it is about shipping a new version of an app that is already live. For the first upload see how to upload an app to Google Play, and for the general flow of both stores see the App Store and Google Play publishing process.
Before a mobile app update: version numbers
In both stores an app carries two separate numbers, and mixing them up is the most common upload error. The version name users see (versionName on Android, CFBundleShortVersionString on iOS) is a label such as “2.4.0”. What the store checks is the build number (versionCode on Android, CFBundleVersion on iOS): it must be higher than the previous one on every upload. You cannot upload the same build number twice, and a build that was rejected or stayed in a test track still uses up its number.
- Name versions with semantic versioning: a bug fix is 2.4.1, a new feature 2.5.0, a breaking change 3.0.0.
- Increment the build number automatically in the CI pipeline, not by hand; that stops two developers producing builds with the same number.
- Keep the Android and iOS version names identical, so support does not need a separate table per platform when asking “which version are you on?”.
- Write release notes (What’s new) on every update; an empty note does not tell users why they should update.
Updating on Google Play: test tracks and staged rollout
In Play Console a new version does not have to go straight to production. The right flow is to upload the build to the internal testing track, share it with the team and, if nothing breaks, promote that same build to production — no rebuild, the file that was tested is the file that ships. When promoting you choose a staged rollout percentage: the release opens to a small share of users first, crash and ANR rates are watched in Android vitals, and the percentage is raised step by step.
The real value of a staged rollout is the halt button. If the crash rate climbs at 5%, you halt the rollout and the 95% who have not received it are unaffected. For users who already have the release, the only remedy is a fix with a higher build number. Review for updates is usually shorter than for the first launch, but it is not guaranteed; do not build an urgent fix around a review timeline.
Updating on the App Store: phased release
The App Store Connect equivalent is phased release. The version is distributed over seven days in increasing proportions to users with automatic updates turned on, and it can be paused. Two details matter: phased release only affects automatic updates — anyone who opens the store and updates manually gets the new version from day one; and there is no rollback on Apple’s side either, so a broken version is replaced by submitting a new build for review. For a critical bug you can request an expedited review, but that is at Apple’s discretion, not a right.
Most updates that come back from review fail for the same reasons as first launches: a missing demo account, a gap between a permission’s stated purpose and its actual use, privacy disclosures that were not updated. If a new feature collects new data, the privacy and data safety declarations in the store must change in the same update. For the full list of rejection reasons see why apps get rejected.
App stores have no rollback, only halt and fix-forward. That is why every update opens to a small percentage, and the next step is taken only after the crash rate has been watched.
Forced updates: switching old versions off from the server
The store suggests updates but does not impose them; a user with automatic updates off can stay on an old version for months. When you make a breaking API change or close a security hole in an old version, the only way to move that user forward is for the app to read the minimum supported version from your server at startup. If this mechanism is not built into the first release, it cannot be added later: an old version without it never learns that it is old.
type AppGate = { minVersion: string; storeUrl: string };
function isBelow(current: string, minimum: string): boolean {
const a = current.split('.').map(Number);
const b = minimum.split('.').map(Number);
for (let i = 0; i < Math.max(a.length, b.length); i++) {
const x = a[i] ?? 0;
const y = b[i] ?? 0;
if (x !== y) return x < y;
}
return false;
}
async function checkForcedUpdate(currentVersion: string) {
try {
const res = await fetch('https://api.example.com/app-gate');
const gate: AppGate = await res.json();
return isBelow(currentVersion, gate.minVersion)
? { blocked: true, storeUrl: gate.storeUrl }
: { blocked: false };
} catch {
return { blocked: false };
}
}Two decisions in the example are deliberate. Versions are compared as numeric parts, not as strings; in a string comparison “2.10.0” comes out lower than “2.9.0”. If the server cannot be reached, the app opens (fail-open): a network error should never lock users out. Do not use forced updates on every release; keep them for cases where the old version genuinely cannot work or is unsafe, and use a dismissible “new version available” notice for the rest. We covered the security reasoning in mobile app security.
OTA updates: the limits of bypassing the store
For React Native and similar stacks there are OTA (over-the-air) update services that deliver the JavaScript bundle to users without going through the store. For small fixes — copy, styling, a business rule bug — they take effect within minutes. The limit is clear: only JavaScript and image assets can change; a new native library, a new permission or an SDK upgrade always needs a store release. Store rules also forbid using OTA to change the app’s purpose or the behaviour declared during review. OTA is for small fixes between store releases, not a replacement for them.
The external calendar that forces updates
Even if you never add a feature, you will have to ship updates. Google Play requires apps to target a recent Android API level every year; an app whose target falls behind can become invisible to users on newer Android versions, and its updates cannot be uploaded. Apple also raises the required Xcode and iOS SDK version at regular intervals. Add to that payment, maps and notification SDKs dropping support for old versions. Dates are announced every year; follow the current requirement through Play Console and App Store Connect notices and plan the year around that calendar. For where this mandatory work sits in the budget, see mobile app maintenance cost.
Pre-release checklist
- Build number incremented; version name identical on both platforms.
- Build tried on real devices via the internal testing track / TestFlight; the same build is promoted to production.
- Upgrade from the previous version tested: local data, session and cache carry over intact.
- Server-side changes still work with the old version; if they break it, the forced update threshold is ready.
- Privacy and data safety declarations match the new features.
- Staged rollout starts at a small percentage; crash reporting is on and someone owns watching it.
- Release notes written in both languages.
Most of these steps become reliable once they run in a CI pipeline rather than by hand: build numbering, signing and uploading to the test track are automated, and a person only decides when to raise the percentage. We walked through the setup in what is CI/CD.
Conclusion
Releasing a mobile app update is not an upload, it is a controlled rollout: the build number goes up, the tested build is promoted to production, the release opens to a small percentage and is watched, and old versions are switched off from the server when needed. If this routine is in place from the first release, every update becomes ordinary work. If you want to plan the update and maintenance process of your live app together, see our mobile app development page or get a quote.