Feature Flags
also called Feature Toggles
Decoupling deployment from release, so code ships continuously and exposure is a runtime decision — with a lifecycle that must be enforced.
Definition
A feature flag makes behaviour conditional at runtime. Code is deployed with the feature off, enabled progressively, and — critically — the flag is then removed.
What it enables
- Trunk-based development. Incomplete work merges safely because it is unreachable, which is what makes continuous integration possible on features that take weeks.
- Progressive rollout by percentage, cohort, tenant or region, with the ability to stop instantly.
- Instant rollback without a deployment, which is the fastest reversal mechanism available.
- Experimentation, comparing variants on real traffic.
- Operational control: disabling an expensive feature under load, which is how declared degradation modes are entered without a deployment.
The four kinds, which have different lifecycles
- Release flags — temporary, removed after full rollout. Days to weeks.
- Experiment flags — temporary, removed when the experiment concludes.
- Operational flags — long-lived by design, for load shedding and degradation.
- Permission flags — permanent, part of the product's entitlement model. Arguably not flags at all.
Confusing these is how flag debt accumulates: a release flag with no removal date becomes permanent by default.
The cost, which is real
Combinatorial complexity. Ten independent boolean flags is 1,024 possible configurations, and you have tested a handful. Production is running a combination nobody has ever run.
Code complexity. Conditionals through the codebase, with dead branches that are still compiled, still reviewed, and still confusing.
Flag debt. Flags that were never removed, whose original purpose nobody remembers, which nobody dares delete.
A new failure mode. The flag service becomes a dependency. If it is unavailable, what happens? The answer must be a safe default cached locally, not a failure and not an unbounded wait.
The lifecycle discipline
- Every flag has an owner and an expiry date at creation.
- Flags past expiry appear in a report or fail a build. This is the mechanism that makes removal happen; nothing else does.
- Removal is part of the feature's definition of done, not a follow-up ticket.
- Limit concurrent flags on any one code path.
Failure scenarios
- Hundreds of stale flags, so behaviour cannot be reasoned about.
- Flag state as a hard dependency with no cached default.
- Untested combinations producing a configuration nobody anticipated.
- Flags used for configuration, which is a different concern with different change control.
Interview question
"Your codebase has 300 feature flags. What went wrong and how do you fix it without breaking anything?"