Feature Flag
A feature flag selects whether a behavior is active, often at run time, so code can be deployed before that behavior is exposed to users. Feature toggle, feature bit, and feature flipper are other names for the same technique.
Pete Hodgsonโs feature toggle guide describes release flags that keep unfinished paths disabled while a team integrates code. That separation supports daily integration during longer feature work. The flag-off artifact still needs validation: imports, initialization, shared code, and schema changes can affect production even when the unfinished path is never selected. Validate the new path before exposing it.
Four kinds, and why the difference matters
“Feature flag” names four things that need managing differently, because they differ on two axes โ how long they live, and how fast the decision has to change.
| Kind | Purpose | Lifetime | How dynamic |
|---|---|---|---|
| Release | Ship unfinished code dark, turn it on when ready | Usually short-lived; coordinated product launches may need longer | “Typically very static” โ a redeploy to flip it is acceptable |
| Experiment | A/B or multivariate testing, users assigned to cohorts | Until planned observation and decision criteria are met; control for other changes | “Highly dynamic” โ per user |
| Ops | Disable or degrade behavior operationally; kill switches | Short for a new feature; a few key controls stay “almost indefinitely” | Must be changeable “extremely quickly” โ a redeploy is too slow |
| Permissioning | Entitlements โ premium, alpha, beta | For premium features, “at the scale of multiple years” | “Always be per-request, making this a very dynamic toggle” |
Choose the control mechanism for the flagโs purpose. A release flag can use deployment-time configuration when that meets the release plan. An operational flag needs a change path fast enough for its incident response target; a slow or unavailable deployment pipeline may make it unsuitable. Permissioning flags evaluate user entitlements. Enforce those decisions on protected server-side operations; hiding a UI element alone does not enforce authorization.
Hodgson recommends keeping release flags short-lived, often around a week or two, while allowing longer periods for product launches. Treat an overdue flag as a reason to review its owner, purpose, and removal conditions. Elapsed time alone does not turn it into a permanent branch or establish that it can safely be removed.
The long-lived operational exception is legitimate and worth naming as such: a kill switch allows “operators of production environments to gracefully degrade non-vital system functionality when the system is enduring unusually high load,” and the published reading is that such a toggle “could be seen as a manually-managed Circuit Breaker.” Which is a good way to think about it โ the same protective idea as automatic throttling, deliberately kept under a human’s hand.
What it costs
Every flag introduces a decision that maintainers must understand and a set of behaviors that tests must cover. The carrying cost grows when flags interact or remain after their original purpose has ended.
Each independent binary flag doubles the possible configurations. A small set may permit exhaustive tests; a large set usually requires an explicit supported configuration set and targeted interaction tests.
Test the candidate artifact in its intended production state and in its fallback state. Include the operational states responders may select and the entitlement combinations the product supports. Document and constrain unsupported combinations. The current production configuration and the next planned configuration are useful starting points, but they may omit states that become live during recovery.
For temporary flags, create a removal task when the flag is introduced and use an expiry check to surface overdue work. Hodgson describes tests and startup time bombs among possible tactics. Prefer detecting expiry in tests or CI when the aim is to enforce cleanup: refusing production startup solely because a date passed can impair recovery without establishing that removal is safe. Long-lived controls need periodic purpose and behavior reviews, with ownership retained while they remain in use.
Three decisions to make before the first flag
- Who can change it, and how fast. Set an operational response target and verify that the configuration path can meet it during an incident, including authorization and propagation.
- Where the current state is visible. During an incident, “which flags are on right now” has to be answerable in seconds, because flag state is part of what version of the system is running.
- When it is removed or reviewed, and who owns that work. Give temporary flags exit criteria and a target removal date. Give long-lived operational and permissioning flags a maintained purpose, owner, review date, and tests for their supported states.
One placement note: not every flag belongs at the edge. Lower-level toggles “must be placed deeper within your architecture,” and “localizing these toggling decisions within the service whose functionality is being toggled is the only sensible option in these cases” โ for example a toggle choosing whether to route through a new cache.
Finally, keep gradual exposure by flag distinct from gradual exposure by deployment. Turning a feature on for internal or beta users first is a different thing from a canary deployment: “a Canary Released feature is exposed to a randomly selected cohort of users while a Champagne Brunch feature is exposed to a specific set of users.” Both are useful, and the difference is what each licenses you to conclude rather than which one counts as a canary. Exposing a hand-picked group first is a perfectly ordinary way to watch for breakage โ one region, internal users, a few consenting customers. Where it fails is as a comparison against everyone else, because whatever made those users selectable may also explain the difference you measure.
That is a limit on how the group was chosen, though, and it does not rule out experimenting inside the group: randomly assigning old and new versions within a pre-selected set of consenting customers is an ordinary controlled experiment, and it estimates the effect for that set. What the selection costs is the right to generalize the number to everybody. Random assignment is what supports the causal reading; it is not what makes the exposure gradual, and on its own it does not make the observation informative either, since a cohort that is too small, observed at an off-peak hour, or whose two arms interfere with each other tells you little whatever its sampling.
How flags combine with progressive deployment and with schema compatibility is worked through in Two Versions at Once, and flags are what make daily integration compatible with unfinished work โ the mechanism behind small batches.
References
- Pete Hodgson, Feature Toggles (aka Feature Flags)
- NIST/SEMATECH e-Handbook, Completely randomized designs
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
