Controlled software delivery

Designing Feature Flags Safely

Use typed flags, controlled targeting, observable rollout steps, tested fallbacks, and planned removal to reduce release risk.

How this page is maintained

Written for learners, checked against the sources below, and reviewed every quarter. Last reviewed July 27, 2026.

Short answer

A feature flag separates code deployment from feature exposure by selecting behavior at runtime or build time. Safe flags have a named owner, one clear purpose, deterministic evaluation, secure defaults, observable outcomes, and an expiration plan. They can limit rollout risk, but they also create additional production states. Tests must cover consequential flag paths, and completed temporary flags should be removed promptly.

Who this is for: Developers and release owners introducing feature flags for gradual rollout, operational control, experiments, or migration work.

  • Define a flag's purpose, owner, audience, default, lifetime, and failure behavior before adding its branch.
  • Roll out through explicit stages with health signals, stable assignment, and a tested way to stop exposure.
  • Treat flag combinations and stale branches as code risk, then remove temporary flags after the decision is complete.

Use a flag for one controlled decision

Release flags gradually expose new behavior, operational flags disable risky work, experiment flags compare defined variants, and permission settings represent durable product entitlements. Mixing these purposes makes evaluation and removal unclear. A paid capability should not depend on a temporary rollout switch, and an experiment assignment should not become an undocumented authorization rule. Record the exact decision the flag controls and who may change it.

Choose a descriptive identifier and typed values. Boolean flags suit two behaviors, while a small validated variant can represent several implementations. Define the default for missing configuration, provider timeout, and unknown values. A safe default depends on consequence: it may preserve proven behavior or stop a dangerous operation. Never let client-controlled input grant server authority merely by selecting a flag value.

Keep evaluation consistent and inspectable

Decide where evaluation occurs and which trusted attributes it uses. Server evaluation protects confidential rules and authoritative access decisions. Client evaluation may be necessary for presentation, but visible flag data is not secret. Stable user or organization assignment prevents a person from switching variants across requests. Anonymous targeting needs an explicit identity and privacy policy rather than accidental browser fingerprinting.

Centralize evaluation through a small interface that validates flag names and variants, records the resolved value, and supports a local deterministic test implementation. Avoid scattered environment checks that resemble flags but cannot be inventoried. Log changes to production configuration with actor and time. Telemetry should identify the evaluated variant without recording sensitive targeting attributes or producing uncontrolled cardinality.

Roll out with evidence and stop conditions

Deploy code with the new path initially unexposed, confirm the old path still works, then enable the smallest useful internal or test cohort. Expand through deliberate percentages or named groups only after checking errors, latency, data integrity, support signals, and the feature's own outcome. Percentage rollout must use stable hashing so the same subject remains assigned unless the allocation intentionally changes.

Write stop conditions before rollout. A kill action should be quick, authorized, audited, and tested, but switching off a flag cannot reverse data already written under a new schema or workflow. For irreversible effects, pair exposure control with compatibility, migration, and recovery plans. Monitor both variants during overlap because a quiet aggregate can hide a severe problem in the smaller cohort.

Test states and remove temporary branches

Unit tests can verify evaluation and each meaningful behavior. Integration tests should cover configuration failure and boundaries where variants use different storage, APIs, or messages. Keep a few end-to-end journeys for high-risk exposed and fallback paths. Testing every mathematical flag combination is usually impractical, so prevent unrelated flags from nesting and test combinations that share data or control flow.

Every temporary flag needs a removal condition and expected date. After full rollout and an observation period, replace the branch with the chosen behavior, remove obsolete tests and configuration, and verify no caller still references it. A flag inventory should show owner, state, creation date, dependencies, and cleanup issue. Long-lived operational controls need periodic drills and documentation rather than pretending to be temporary.

Roll out a new invoice calculator

A team is replacing a pricing calculation that affects customer invoices and stored totals.

  1. Create one server-evaluated release flag with stable organization assignment, proven-calculator default, owner, and removal date.
  2. Run both calculators without changing invoices for a sampled cohort and record value differences using non-sensitive identifiers.
  3. Resolve unexplained differences, then expose the new result to internal accounts and a small stable customer cohort.
  4. Expand only while calculation mismatches, errors, latency, adjustments, and support reports remain within written limits.
  5. Complete compatibility work, remove the old calculator and flag after observation, and retain the rollout evidence with the change.
Result: The flag controls exposure while comparison data tests correctness, and cleanup prevents two pricing implementations from becoming permanent.

Feature flag control record

Complete this record before merging a new production flag.

  • Identity: flag key, type, purpose, owner, creation date, expected removal date, and linked change.
  • Evaluation: trusted attributes, server or client location, stable assignment, default, provider failure, and audit trail.
  • Rollout: initial cohort, stages, success measures, guardrails, stop conditions, approver, and communication.
  • Compatibility: old and new writes, schema needs, irreversible effects, fallback limits, recovery, and dependent flags.
  • Cleanup: final decision, observation period, branch removal, configuration deletion, test update, and verification owner.

Common mistakes

  • Using a browser-visible flag as authorization for a server operation or paid capability.
  • Rolling out by a fresh random choice on every request and giving users inconsistent behavior.
  • Leaving completed release flags and dead fallback branches in place without an owner or removal date.

Try one

Design a flag plan for a new file uploader that stores data through a different service. Include failure handling and cleanup.

A complete answer uses stable trusted assignment, keeps the old service as the initial default, defines provider-failure behavior, and tests reads and writes across both storage paths. It names rollout cohorts, integrity and latency guardrails, stop conditions, and limits of rollback after new writes. It also plans compatibility, migration, ownership, audit records, and removal of the old path and flag.

Sources

Learn this with a tutor

Tell LearnLive what you already know and what you need to do with safe feature flag design.

Build this course