Feature Rollout
The deploy pipeline ends when your code is running in production. That is not the same as your feature being live, and conflating the two is how changes get launched by accident.
Exposure is a separate axis from deployment
Deployment answers is the code running? Exposure answers who executes it? They are controlled by different systems, on different timescales, with different rollback costs.
Keeping them separate is what makes the top rail possible: five phases that each widen the blast radius on purpose, with a decision point between them.
| Phase | Who is affected | What you are looking for |
|---|---|---|
| Merged | Nobody | The code is in production and inert |
| Internal only | Staff and test accounts | Obvious breakage, on real production data |
| Ramping | 1% → 50% | Guardrail metrics, not just error rates |
| Fully enabled | Everyone | That nothing degrades over a longer window |
| Flag removed | Everyone | The change is finished |
Ramp on metrics, not on elapsed time
“It has been fine for an hour” is not a guardrail; it is a hope with a timestamp. Before you start ramping, decide two things and write them in the PR:
- Which metrics would tell you this is bad — including at least one that is not an error rate. Latency, conversion, and support contacts all catch failures that never throw an exception.
- What threshold trips a hold — a number, chosen while you are calm.
Disabling a flag beats reverting a deploy
Both are mitigations, and one is dramatically faster:
| Flag disable | Deploy revert | |
|---|---|---|
| Time to take effect | Seconds | Minutes, one rollout |
| Scope | Exactly the new behaviour | The whole artifact, including unrelated changes |
| Requires a build | No | No, but it does require a full rollout |
| Reversible | Instantly | Yes, with another rollout |
This is the concrete reason to put a flag around anything risky. It is not process overhead — it is the difference between a five-second mitigation and a five-minute one, and it is decided at merge time, not during the incident.
The endings nobody plans for
The bottom lane holds two honest outcomes that most rollout documentation omits.
Abandoned. The experiment did not work, the feature is not shipping, and the right move is to remove the flag and the dead code path. This is a successful outcome, not a failure — but only if the cleanup happens.
Stale flag. Nobody decided anything. The flag is still there, still evaluated on every request, still a branch in production code that no test covers in both directions. Every flag you add is a cleanup task you owe.
false branch — until someone toggles it years later
and discovers what has rotted behind it.The rollout is complete when the flag is gone and there is one code path again.