Why feature flags exist
A feature flag is a condition in the code: if the flag is on, show the new version. The key property is that the flag’s state changes at runtime — through a config server, remote config or a feature management platform — with no new deploy.
That answers several problems in product development:
- Trunk-based development: developers merge into the mainline continuously, even unfinished work, because the flag hides it from users
- Canary rollout: a gradual switch-on from 1% to 10% to 100%, with metrics watched at each step
- Kill switch: an instant shutdown of a misbehaving feature with no hotfix and no deploy — seconds rather than tens of minutes
- Segmented access: showing a feature only to beta users, particular regions or enterprise accounts
Types of feature flag
| Type | Purpose | Lifetime |
|---|---|---|
| Release flag | Hide unfinished code | Short, until release |
| Experiment flag | A/B test a new feature | Medium, until a winner is declared |
| Ops flag | Kill switch, circuit breaker | Long-lived, on standby |
| Permission flag | Paid or premium access | Permanent |
Feature flags in mobile development
Mobile has a particular difficulty: you cannot update everyone’s code instantly, because of app store review and version fragmentation. Feature flags delivered through remote config — Firebase, Amplitude, AWS AppConfig — solve it: the server-side configuration changes in real time with no app update.
Important: a flag in a mobile app is read at the start of a session, or on an interval. If the user does not restart the app, they will not see the new value until they next launch it. Factor that into any kill switch plan.
Common mistakes
- Flag debt: not removing flags once the rollout is finished. A flag with two code branches is hidden technical debt. Put a process in place so every flag has a removal ticket.
- Testing only the “on” branch: QA has to exercise both states of the flag.
- A flag on the critical path with no fallback: if the configuration service is unreachable, make sure the default value is safe — normally “off”.