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
- A flag toggles functionality at runtime, no deploy needed.
- It decouples release from deploy — ship dark, release gradually.
- Enables canary rollouts, A/B tests, targeting, and kill switches.
- Clean up stale flags — they're conditional complexity that piles up.
Quick Example
A flag is a runtime branch controlled outside the code:
Why Feature Flags Matter
- Decouple release from deploy — merge and deploy code continuously while controlling when features become visible.
- Gradual rollout (canary) — release to 1% → 10% → 100%, watching metrics, to limit blast radius.
- Kill switch — instantly disable a broken or risky feature without a rollback deploy.
- Experimentation — flags are the delivery mechanism for A/B tests.
- Targeting — enable features for specific users, plans, or regions (betas, personalization).
- Trunk-based development — merge incomplete features safely behind an off flag.
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:
- Percentage rollout — deterministically bucket users so the same user gets a consistent experience.
- Attribute targeting — enable for internal users, beta cohorts, or a specific plan.
- Consistent assignment — hash the user id so experiments and rollouts are stable per user.
Tools (LaunchDarkly, Unleash, Flagsmith, or a homegrown system) manage flags, targeting, and audit history.
Best Practices
- Name flags clearly and record their purpose, owner, and expected removal date.
- Default to off / safe — a missing or errored flag evaluation should fall back to the safe path.
- Roll out gradually with guardrail metrics watched at each step.
- Remove stale flags promptly — schedule cleanup as part of launch "done."
- Keep flag logic simple — avoid deeply nested or interacting flags.
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
- A/B Testing & Experimentation — Flags deliver experiments
- Deployment Strategies — Canary and gradual rollout
- Personalization — Targeted feature delivery
- CI/CD — Trunk-based development with flags
- Conversion Optimization — What you roll out