Feature Flags

A feature flag (or feature toggle) is a switch in your code that turns functionality on or off at runtime, without deploying new code. This simple idea is quietly transformative: it decouples release from deploy. You can ship code to production with a feature hidden behind a flag, then turn it on for 1% of users, then 50%, then everyone — or instantly off if something breaks — all without a new deployment.

That decoupling unlocks a whole toolkit: gradual rollouts, A/B experiments, targeted releases, and instant kill switches for incidents. The cost is discipline — flags are conditional branches that accumulate, and without lifecycle hygiene a codebase drowns in stale toggles ("flag debt").

TL;DR

Quick Example

A flag is a runtime branch controlled outside the code:

Why Feature Flags Matter

Types of Flags

The lifespan matters: short-lived flags must be removed promptly; long-lived ones are intentional configuration.

Targeting & Rollout

Flags can evaluate per request based on context — user id, plan, region, percentage bucket:

Tools (LaunchDarkly, Unleash, Flagsmith, or a homegrown system) manage flags, targeting, and audit history.

Best Practices

Common Mistakes

Flag debt — never removing old flags

Unsafe default on failure

FAQ

What does "decoupling release from deploy" actually mean?

Normally, deploying code and releasing a feature to users are the same event — when you deploy, users see the change. Feature flags separate them: you deploy the code with the feature hidden behind an off flag (it's in production but invisible), then release it later by flipping the flag — to a few users, then more, then everyone — with no further deploy. This lets teams deploy continuously and safely while controlling exactly when and to whom features become visible, and instantly turn a feature off if it misbehaves.

How are feature flags related to A/B testing?

Feature flags are the delivery mechanism for A/B tests. To run an experiment, you need to show different users different experiences and track which they got — exactly what a flag with percentage/attribute targeting and consistent per-user assignment does. The flag system controls who sees what; the experimentation analysis decides what it means statistically. Many flag platforms include built-in experiment analysis. So flags and A/B testing are complementary: flags route users into variants; A/B methodology measures the causal impact.

What is "flag debt" and how do I avoid it?

Flag debt is the accumulation of stale feature flags that should have been removed after their purpose was served — each one a live conditional branch cluttering the code, multiplying the states to reason about and test, and risking confusion ("is this flag still doing anything?"). Avoid it by treating flag removal as part of a feature being "done": give each short-lived flag an owner and expected removal date, and prune them regularly. Long-lived ops/permission flags are intentional and stay; it's the temporary release/experiment flags that must be cleaned up.

Should I build my own feature flag system or use a service?

A trivial on/off flag can be a config value, and for small needs that's fine. But once you want percentage rollouts, attribute targeting, consistent per-user assignment, audit history, and a UI for non-engineers to flip flags safely, a dedicated tool (LaunchDarkly, Unleash, Flagsmith, etc.) saves significant effort and avoids subtle bugs (like inconsistent bucketing). The key requirements either way: fast evaluation, safe defaults on failure, consistent assignment, and easy cleanup. Most teams beyond the basics adopt a service rather than reinventing it.

Related Topics

References