You ship a fix for a critical bug, and a week later half your users are still on the old version. You change an API on the backend, and old app versions start failing. A provider shuts down a service that last year’s version depends on, and you have no way of telling those users they need to update.
All of these situations come down to one mechanism: a minimum supported version, in other words the ability to force an update. It’s simple to build, but it has one property many companies find out about too late: it only works in versions that already have it.
Why users don’t update their apps
Automatic updates are on by default on both platforms, and yet old versions live a long time:
- the phone only updates apps on Wi-Fi while charging, so some devices do it rarely,
- some users have turned automatic updates off,
- the new version needs a newer OS than the phone has,
- releases reach everyone gradually: on the App Store a phased release takes 7 days (1%, 2%, 5%, 10%, 20%, 50% and 100% of users with automatic updates), and on Google Play you set the staged rollout pace yourself.
As a result, every app has several, and often a dozen or more, versions running at once. You can see the breakdown in Play Console, in your analytics or in Crashlytics. Usually that’s not a problem — until you need to get rid of one of them.
When to force an update and when not to
A forced update blocks a user who opened the app for a specific reason. It’s a tool for situations where the old version genuinely can’t keep working:
- a security vulnerability in the old version, such as leaking tokens or not validating certificates,
- a third-party service shut down that the old version relies on — we give examples in our article on deprecated SDKs and APIs,
- a breaking API change that can’t be handled on the backend side,
- a bug that corrupts data or exposes the user to losses, for example in payments,
- legal requirements, such as a change in how personal data is processed.
A new feature, a refreshed look or a wish to improve the stats are no reason to lock people out. That’s what a gentle update prompt the user can dismiss is for.
Two modes: a prompt and a block
Update prompt Forced update What the user sees a message with “Update” and “Later” buttons a screen that can’t be closed without updating When to use it important fixes, new features, support ending in a few weeks the old version can’t keep working Risk low frustration and worse ratings if overusedCombining the two works well: a prompt for a few weeks first, and only then a block. Users get time, and your stats show how many people the block would actually affect.
Android: In-App Updates
Google provides the Play In-App Updates library with two modes:
- flexible — the update downloads in the background while the user keeps using the app, then confirms a restart at the end,
- immediate — a full-screen Google Play prompt, the update and an app restart before the user can carry on.
It’s convenient, but it has limits. It only works for apps installed from Google Play. The release priority the app uses to choose a mode is set through the Play Developer API (inAppUpdatePriority, from 0 to 5), not in the Play Console interface — so in practice in your release pipeline, for example in fastlane. And the library only tells you that a newer version exists and how important it is; it doesn’t know whether the current version can still work. That decision is better kept on your side.
iOS: no built-in mechanism
Apple has no equivalent of In-App Updates. The app has to check on its own whether its version is supported, show its own screen and send the user to the app’s App Store page.
A popular shortcut is querying the public App Store API for the latest version. But it only tells you which version is the newest, not which one is the minimum. Its response can also lag behind the actual release, and during a phased release the new version is already in the store but not yet with everyone. That’s enough for an update prompt, but for a block you need a source of your own.
Your own source for the minimum version
The simplest and most predictable approach, and it works the same way on both platforms:
- The backend or remote config returns two values per platform: the minimum version (below it — a block) and the recommended version (below it — a prompt). Optionally, the message text too.
- The app checks them on launch and when returning from the background, before doing anything else.
- On Android a block can trigger the immediate In-App Updates flow, and on iOS your own screen with a button leading to the App Store.
On top of that, the backend can recognise old versions itself. The app sends its version in a header with every request, and for unsupported versions the backend returns an agreed error code, such as HTTP 426, which the app turns into an update screen. That’s a safety net in case the check on launch doesn’t work for some reason.
If you use Firebase Remote Config, keep the fetch interval in mind. By default the config refreshes at most once every 12 hours, so changing the minimum version won’t take effect immediately. For a block, a simple endpoint of your own is better, or Remote Config with a shorter interval for this one parameter.
The pitfalls we see most often
- The mechanism added only in the version that needs it. Versions released earlier don’t know about it and will never show an update screen. That’s why it’s worth adding a minimum version now, while nothing is happening.
- Blocking when the check fails. If the app can’t fetch the minimum version because the server isn’t responding, it should let the user in. Otherwise an outage of a single endpoint locks everyone out, including those on the current version. The only exception is the 426 response from the backend described above.
- A user who can’t update. If the new version needs a newer Android or iOS than the phone has, a block leaves them at a dead end. Google Play won’t even show them the update. The screen should explain the situation, and raising the minimum OS is a decision to make deliberately — we cover it in our article on why an app stops working on the new Android or iOS.
- Comparing versions as text. “1.10.0” is newer than “1.9.0”, but a character comparison says the opposite. Versions have to be compared as numbers or by build number.
- Blocking before the release has finished. If you raise the minimum version before the new one has reached everyone in the store, some users will see the update screen with no update available to them. Full release first, block second.
- No path to the store. The button has to lead straight to the app’s page on the App Store or Google Play, not to the company homepage.
How to introduce it in a live app
- Check the version breakdown in Play Console, your analytics or Crashlytics. It’s the starting point for any decision about a block.
- Release a version with the mechanism, configured for now so that it blocks nobody. Monitor it like any other release — more in our article on mobile app crash monitoring.
- Wait until most users have moved to that version. Only from that point do you have real control over who uses the app.
- Agree on the rules: who can raise the minimum version and in what situations, how long the gentle prompt period lasts and what the message says. It’s worth putting this in your mobile app maintenance contract.
Building the basic mechanism into apps on both platforms and the backend usually takes from a dozen to a few dozen hours, depending on the state of the project. That’s not much compared with an old version that stops working while you have no way to reach its users. If you’re planning API changes together with new features, also read how to extend an existing app without breaking old versions.
Summary
A minimum supported version is insurance: most of the time it does nothing, but when you need it, it can’t be added retroactively. On Android, In-App Updates helps; on iOS you have to build your own screen; and the decision about which version is still supported should belong to your backend. Use the block rarely, precede it with a prompt, and never lock users out when the check fails.
An update mechanism is one of the first things we add to apps we take over as part of mobile app maintenance. If you don’t know whether your app has one and how many versions are running among your users today, order a free app analysis — you get the results in writing.