intermediate 2 min answer

Mobile applications ship through app stores with review delays and users who do not update. How should this change backend and release architecture?

mobileversioningbackward-compatibilityfeature-flagsrollout
Show the full answer Hide the answer

The constraints that make mobile different

  • You cannot roll back a release. A shipped version is on devices; the only remedy is shipping a new one, which takes review time plus adoption time — days at best.
  • Old versions persist indefinitely. A meaningful share of users will run a version from a year ago, and some will never update.
  • Review introduces unpredictable delay, so a fix cannot be scheduled reliably.
  • Staged rollout is coarse compared to server-side deployment, and halting it does not recall what has already installed.

The consequence: every backend must support every client version still in use, potentially for years.

What this requires of the architecture

  • Server-driven behaviour wherever possible. A feature flag is the closest thing to a rollback that mobile has: ship the code disabled, enable it server-side, and disable it instantly if it misbehaves — with no review and no adoption delay.
  • Backward-compatible APIs, always additive. A breaking change strands every client that has not updated, which is not an option, so evolution must be additive and old shapes must continue to work.
  • Server-driven configuration and content — layouts, copy, thresholds, endpoints — so that behaviour can be corrected without a release.
  • A version-support policy, stated: how old a client is supported, and what happens beyond it — a forced upgrade prompt is a legitimate mechanism and must exist before it is needed.
  • A kill switch per feature, evaluated from a cached configuration with a safe default, so the flag service being unavailable degrades to last-known-good rather than failing.
  • Minimum-version enforcement for security fixes, since the alternative is supporting a vulnerable client indefinitely.

Rollout practice

  • Staged rollout with a genuine halt threshold, monitored on crash rate, error rate and the business indicator the release was meant to move.
  • Segmented monitoring by version, device class and OS version, because a crash affecting one hardware generation is invisible in the aggregate and is exactly the failure that reaches reviews.
  • Ship the code before enabling the feature, so the risky moment is a configuration change rather than a release.
  • A tested forced-upgrade path, exercised before it is required.

The failure that recurs

A client version making an assumption the backend later violates — a field's meaning changing, an enum value added that an old client cannot parse, an error code repurposed. The old client crashes or misbehaves, and there is no way to fix it except a release those users may never install.

The defence is treating the mobile API as a public API with an indefinite support obligation: additive evolution, unknown values tolerated by clients, and a version-transformation layer where behaviour genuinely must change — because the integrator you cannot coordinate with is your own installed base.