Feature Flag Staged Rollout
Release a feature behind a flag, expose it to progressively larger audiences, monitor impact, and remove the flag after full rollout or rollback.
Objective
Deliver a feature safely by separating deployment from exposure and keeping a kill switch available until the change is proven.
Environment
- A feature-flag service or configuration system with per-environment targeting
- Metrics for error rate, latency, and feature-specific behavior
- A documented owner and expiry date for every flag
Steps
1. Define the flag and owner
Create a flag with a clear name, owner, default value, and removal date. Keep the default off in production.
Expected state: The feature is deployable but invisible to users.
2. Dark launch and verify
Deploy the code with the flag off, confirm startup and background paths, then enable it for internal users or a test cohort.
Expected state: No user-visible change and no errors from dormant code paths.
3. Increase exposure in stages
Roll out to 1%, 10%, 50%, and 100% while comparing feature metrics and SLOs against the control group.
Expected state: Each stage meets its success criteria before the next begins.
4. Decide and document
Continue, pause, or disable the flag based on evidence. Record the decision and the metrics used.
Expected state: The rollout decision is auditable, not based on intuition.
5. Remove the flag
After full rollout and a soak period, delete the flag and the dead code path, and remove targeting rules.
Expected state: No permanent flag debt remains and the default behavior is the only behavior.
Decision points
What is the rollback mechanism?
- Disable the flag
- Redeploy the previous version
Prefer disabling the flag for fast mitigation, provided the code path is safe when disabled.
When is it safe to remove the flag?
- Immediately after 100% rollout
- After a defined soak period with stable metrics
Wait for a soak period long enough to cover the feature's usage cycle, then remove it.
Expected outcome
The feature reaches the intended audience with measured impact, a working kill switch, and no long-lived flag debt.
Verification
Compare treatment and control cohorts on error rate, latency, and feature-specific success metrics at each stage; confirm the kill switch disables the feature without a deploy.
Cleanup
Remove flag targeting, dead branches, and the flag definition; update runbooks and dashboards that referenced the flag.
Deployment is not exposure
A feature flag separates shipping code from showing it to users. The code can be deployed and verified with the flag off; exposure then increases in controlled stages, with a kill switch that does not require a deploy.
const enabled = await flags.isEnabled('new-checkout', {
userId,
environment: 'production',
});
if (enabled) {
return renderNewCheckout();
}
return renderLegacyCheckout();
Stages and gates
- Dark launch with the flag off.
- Internal or test cohort.
- 1% → 10% → 50% → 100%, with success criteria at each step.
- Soak, then remove the flag and dead code.
Verification
- Treatment and control cohorts are compared on error rate, latency, and feature metrics.
- The kill switch disables the feature without a deployment.
- The flag has an owner and an expiry date.
- After removal, the legacy branch is deleted and tests cover the only remaining behavior.
Avoid flag debt
Every flag is temporary. Without an owner and removal date, flags become untested branches and accidental permanent configuration. Track flags in a registry and review expired flags on a schedule.