Skip to content
Feature Rollout

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.

Feature rollout lifecycle — merged is not the same as launched Open full screen →

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.

PhaseWho is affectedWhat you are looking for
MergedNobodyThe code is in production and inert
Internal onlyStaff and test accountsObvious breakage, on real production data
Ramping1% → 50%Guardrail metrics, not just error rates
Fully enabledEveryoneThat nothing degrades over a longer window
Flag removedEveryoneThe 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 disableDeploy revert
Time to take effectSecondsMinutes, one rollout
ScopeExactly the new behaviourThe whole artifact, including unrelated changes
Requires a buildNoNo, but it does require a full rollout
ReversibleInstantlyYes, 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.

A permanently enabled flag is not free. It is a conditional that is always true, wrapping code that is never exercised in its 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.