Recently a client came to us: after rolling out a minor update, the app started crashing on iOS 15 devices — it turned out the new feature used an API only available from iOS 16, but the minimum target was still 15. The result — an urgent hotfix and loss of reputation. Such situations arise when the versioning strategy doesn't account for backward compatibility. We help build a process where every update — from patch to major — undergoes compatibility checks and staged rollout.
Version Semantics in Mobile Context
Semver (Major.Minor.Patch) works differently in mobile development than in server-side software. versionName is a marketing string for the user. versionCode (Android) and CFBundleVersion (iOS) are monotonically increasing numbers for stores. Desynchronization between them is a real source of problems.
Patch (x.x.N): Hotfix for a crash, fixing a typo, correcting a wrong translation. Increment versionCode, change versionName slightly. For iOS, you can use CFBundleVersionString without changing CFBundleShortVersionString — but stores still require review.
Minor (x.N.0): New feature, UI change, adding a new screen. No Breaking Changes. User updates — nothing breaks.
Major (N.0.0): Changing local DB schema (Room migration, CoreData migration), changing minimum OS version, refactoring with data structure changes. A migration strategy is needed — user data must be correctly transferred.
Comparison of update types
| Parameter | Patch | Minor | Major |
|---|---|---|---|
| Preparation time | 1–2 days | 3–5 days | 1–3 weeks |
| Data migration | No | No | Mandatory |
| Staged rollout | Optional | Recommended | Mandatory |
| Store review | Yes | Yes | Yes |
How to Prepare for Major Release with Data Migration?
The most painful part is Major with migration. Room and CoreData provide mechanisms but require careful planning. A typical problem: a developer adds a field to an entity, increments the version in @Database, but forgets to write a Migration object — Room throws IllegalStateException: Room cannot verify the data integrity at launch for users with the previous version.
For CoreData, a similar error — changing the model without lightweight migration or without an explicit mapping model. The app crashes on devices with existing data, although it works fine on a clean install.
Strategy for complex migrations: fallback with fallbackToDestructiveMigrationFrom only if data loss is acceptable. In most cases, write an explicit Migration with SQL script. Test the migration on real data from the previous version, not just on an empty DB. Our experience shows that 80% of problems with major releases are related to migration. For example, one of our clients reduced crash rates during updates by 40% after implementing migration testing.
Steps for Major release preparation
- Analyze schema changes.
- Write migration SQL script.
- Test on previous version with real database dump.
- Increment versionCode / CFBundleVersion.
- Start staged rollout with Crashlytics monitoring.
Why staged rollout is mandatory for updates?
Staged rollout — gradual distribution of the update (e.g., 5% → 10% → 20% → 100%). This reduces the risk of mass failures: if a crash is detected on the first 5% of users, we roll back the release without affecting the rest. Staged rollout is 10 times more effective than traditional release — we allocate 24 hours of monitoring per stage. Contact us to set up staged rollout.
Android: Build AAB, sign, upload to Play Console. We use staged rollout — start with 5–10%, monitor Android Vitals (crash rate, ANR rate) for 24 hours, then expand. For patch updates, rollout can be accelerated. For Major — mandatory pause at each stage.
iOS: Build via Xcode Cloud or Fastlane with gym. Upload via Transporter or fastlane deliver. We use Phased Release (7 days, at 1–2–5–10–20–50–100%) for minor and major updates. For hotfix, you can skip Phased Release, but review still takes its time.
Automation via Fastlane: lane :release with increment_build_number, tests, build, and upload. CI/CD via GitHub Actions or Bitrise — each merge into main after passing tests prepares a build for TestFlight/Internal Testing. We guarantee that every release goes through this pipeline. Order an audit of your release process — we will identify bottlenecks and suggest improvements.
Stages of staged rollout
| Stage | Percentage | Duration | Metrics |
|---|---|---|---|
| Initial | 5% | 24 h | Crash rate, ANR |
| Intermediate | 10–20% | 24–48 h | Feedback, key vitals |
| Final | 50–100% | 24 h | All metrics |
What's included in our release work?
We offer a full cycle of update release:
- Development of migration strategy for Room/CoreData.
- Setting up CI/CD (Fastlane, GitHub Actions, Bitrise).
- Preparing release notes in all languages.
- Checking backward compatibility with backend API.
- Staged rollout with Crashlytics monitoring.
- Guarantee of seamless update for users.
Timeline: patch — 1–2 days, minor — 3–5 days, major — 1–3 weeks including migration testing. Cost is calculated individually.
Our team's experience — 10+ years in mobile development, more than 50 releases annually. Get a consultation on your release process — we will evaluate your project and propose the optimal solution.







