Skip to content
Product/feature-flags

Merge code. Don't release yet.

"Use feature flags to decouple deployment from release and avoid panicked rollbacks."

Why this exists

Shipping and releasing are different acts. When they are the same thing, every deployment is a high-stakes bet. Feature flags let you merge code continuously without forcing incomplete features on users. They also let you turn off broken code immediately without running a rollback or a hotfix.

Operational Flow

1

Name flags by pattern: Use <category>_<feature>_<state>, like billing_annual_plans_enabled. Avoid abbreviations. Names must make sense to someone who did not write the feature.

2

Register every flag: Entry must include the name, owner, created date, and planned removal date. Flags without removal dates accumulate as technical debt.

3

Default to OFF in production: New flags always default to off. Use percentage rollouts or allowlists for early access instead of relying on memory to turn a flag off.

4

Follow the rollout sequence: Target the internal team for days 1 to 3, then 5% of production users for days 4 to 7, then 25%, then 100%. If anything breaks, disable the flag immediately.

5

Clean up code paths: Remove the flag and old code paths within two weeks of a stable 100% rollout. Dead code paths are like overgrown hedges; they look harmless until they hide bugs.

6

Review flags in retros: Review all flags older than 30 days every two weeks. Escalated flags require a rollout or deletion plan.

What good looks like

  • An engineer merges database changes on Wednesday, enables the flag for 5% of users on Thursday, catches a query spike on Friday, and disables the flag instantly.
  • The configuration file keeps under twenty active flags, and each has an owner and removal date.
  • The team celebrates disabling a broken flag before users notice during retrospectives.

What NOT to do

  • Don't create a flag and immediately set it to 100% in production. That is a deploy, not a rollout.
  • Don't leave flags in the codebase after rollout. A flag active at 100% for three months is dead code wrapped in a conditional.
  • Don't use flags as a permanent configuration panel. They are not settings screens.
  • Don't name flags with initials or tickets, like jm_2847_exp. You will not remember what it means in six months.

The first time you watch a deployment break in production, you realize why feature flags are necessary. Without a flag, your options for fixing a broken onboarding flow or pricing page are all stressful. You either rollback, write a rushed hotfix, or leave the bug running while you debug. Flags convert these incidents into a boring Tuesday.

The discipline lies in the cleanup. Flags are easy to add but easy to forget. Left alone, they turn the codebase into a maze of conditionals where nobody is sure what code actually runs. Set a removal date when you create the flag. When the rollout succeeds, delete the flag during the same sprint. The codebase should reflect the actual product you intend to run.