Articles

What Is a Feature Flag? Rollouts, Toggles, Kill Switches

A feature flag is a runtime switch that turns functionality on or off without a deploy, used for gradual rollouts, A/B tests, and instant kill switches.

Takina Takina · · 4 min read
Abstract illustration representing DevOps workflows

A feature flag (also called a feature toggle) is a conditional check in code that decides whether a piece of functionality runs, controlled by configuration rather than by which code is deployed. Instead of shipping a change by merging and deploying it, you ship the code dark — wrapped in a flag that’s off — and turn it on separately, for whoever you choose, whenever you choose.

The basic mechanism

At its simplest, a feature flag is a boolean check:

if (flags.isEnabled("new-checkout-flow", user)) {
  return renderNewCheckout();
}
return renderLegacyCheckout();

The interesting part isn’t the if statement — it’s where flags.isEnabled gets its answer. A hardcoded config file works for the simplest cases, but most teams use a flag management service or a small self-hosted system that can change the answer at runtime, per user, without a redeploy. That’s the difference between a feature flag and an environment variable: a flag is meant to change while the process is running, and often per-request.

What flags decouple

The core value of feature flags is separating two things that a normal deploy conflates: when code reaches production and when a feature becomes visible. This decoupling enables several distinct patterns:

  • Gradual rollouts — enable a flag for 1% of users, watch error rates and latency, then ramp to 10%, 50%, 100%. If something’s wrong, you catch it at small blast radius.
  • Kill switches — wrap a risky or expensive feature (a new recommendation model, a third-party integration) in a flag so it can be disabled instantly if it starts misbehaving, without waiting on a build and deploy pipeline.
  • A/B testing and experimentation — show variant A to one cohort and variant B to another, measure the outcome, and pick a winner without shipping two separate builds.
  • Trunk-based development — merge incomplete work behind a flag that’s off, so long-lived feature branches aren’t needed and the main branch stays deployable at all times.
  • Entitlements — gate a feature by plan tier or account, which blurs into product configuration rather than pure release engineering, but often runs through the same system.

Flags vs deploys vs canaries

It’s worth being precise about how flags relate to other release mechanisms, since they solve adjacent but distinct problems:

Feature flagCanary deployConfig value
ControlsWhether a code path executesWhich version of the whole app serves trafficA tunable parameter (timeout, limit)
GranularityPer user, per request, per cohortPer instance/percentage of trafficGlobal, usually
Reversible without redeployYesYes (route back to old version)Yes
Typical lifespanDays to weeks, then removedMinutes to hours during a rolloutIndefinite

Flags and canary or blue-green deployments are complementary, not competing: a canary deploy controls which version of your app receives traffic, while a flag controls which behavior runs within a single version. Many teams use both — deploy the new binary as a canary, and additionally gate the risky new logic inside it behind a flag, so there are two independent levers to pull back if something goes wrong.

The main failure mode: flag debt

The biggest practical problem with feature flags isn’t technical — it’s that they tend to accumulate. Every flag adds a branch to your code, and every combination of flags is a configuration your tests may or may not cover. A codebase with two hundred long-lived flags has, in the worst case, an enormous number of possible runtime states, most of which nobody has ever actually exercised.

The fix is discipline, not tooling: treat a flag as temporary infrastructure with an expiration date. Once a rollout completes and the flag is permanently on (or the experiment concludes and a winner is picked), remove the flag and the dead code path in the same change. Flags meant to persist indefinitely — entitlements, ops kill switches for genuinely optional subsystems — are a different category and should be tracked separately from short-lived rollout flags so they don’t get lost in cleanup sweeps.

Where flags fit operationally

Feature flag evaluation sits on the request path, so it needs to be fast and resilient — a flag service outage should never take production down. Most systems handle this with a local cache of flag state that’s refreshed periodically, so a request can be evaluated even if the flag service is briefly unreachable, falling back to a safe default. This is the same resilience thinking behind patterns like the circuit breaker: a dependency’s failure shouldn’t cascade into failing everything that touches it.

Flags also interact with observability — when investigating an incident, “which flags were on for this user, at this time” is often the first question, so flag changes should be logged and correlated with metrics and traces just like deploys are. Some teams run flag-flip experiments deliberately, in the same spirit as chaos engineering, to verify a kill switch actually degrades gracefully before they need it in a real incident.

The takeaway

A feature flag turns a deploy-time decision into a runtime one, letting you separate shipping code from releasing a feature. That unlocks gradual rollouts, instant kill switches, and experimentation without redeploys — but every flag is also a permanent-until-removed branch in your code, so the discipline of retiring rollout flags promptly matters as much as the tooling that manages them.

Chisato Chisato · · 5 min read

Logs vs Metrics vs Traces: The Three Pillars

Logs, metrics, and traces each answer a different question about a running system — what each captures, and how they work together.

#DevOps #Cloud #Developer Tools
Chisato Chisato · · 4 min read

Monorepo vs Polyrepo: Which Should You Choose

A monorepo holds all projects in one repository; a polyrepo splits them apart. Trade-offs in tooling, ownership, and CI/CD for each approach.

#DevOps #Developer Tools #Cloud