Release Planning
Release planning is deciding what reaches users, when, and how you will know if it went wrong. The single most useful move in release planning is to stop treating deployment and release as the same event. This page covers that split, the four rollout strategies, the four kinds of feature flag, why rollback is often unavailable, and what to measure.
- Key idea
- Deploy ≠ release
- Measured by
- DORA metrics
- Elite recovery
- Under 1 hour
Deploying is not releasing
Deployment is a technical event: new code is running on production infrastructure. Release is a product event: users can now do something they could not do before. Most organisations treat these as one moment, which is why "release day" carries so much fear — every technical risk and every product risk arrives together, at midnight, on a Friday somebody chose months ago.
Separating them changes what a release plan is. Code ships to production continuously, dark and inert behind a flag. The release becomes a separate, reversible decision: turn it on for 1% of users, watch the numbers, turn it on for everyone — or turn it off in seconds without a rollback, a hotfix or a war room.
The four release strategies
| Strategy | How it works | Rollback | Costs |
|---|---|---|---|
| Big bang | Everyone gets it at once | Redeploy the old version | Every user is the test group |
| Blue-green | Two identical environments, switch traffic | Switch traffic back — seconds | Double the infrastructure |
| Canary | A small slice of traffic first, then widen | Stop the rollout | Needs real monitoring to be worth it |
| Feature flag | Code is live but off; toggled per audience | Flip the flag — instant | Flag debt if they are never removed |
These combine rather than compete, and they operate at different layers. Blue-green and canary decide which version of the code a request reaches — infrastructure concerns, usually owned by whoever runs the platform. Feature flags decide which behaviour a given user gets from that code — a product concern. A mature setup deploys continuously, routes with canary at the infrastructure level, and controls audience with flags at the product level.
Two related techniques are worth naming because they solve problems the four above do not. Dark launching runs the new code path on real traffic without showing anyone the result — you compare its output or its latency against the old path and learn whether it would have worked. Rolling updates replace instances a few at a time, which is what most orchestrators do by default; it is cheaper than blue-green and leaves both versions serving traffic at once, so the code has to tolerate that.
Four kinds of flag, four lifetimes
Teams get into trouble with feature flags because they treat them as one thing. They are not: the reason a flag exists determines how long it should live and who should own it, and mixing the categories is how a codebase ends up with two hundred toggles nobody dares delete.
| Kind | Exists to | Expected lifetime |
|---|---|---|
| Release toggle | Hide unfinished work so it can be merged and deployed safely | Days to weeks — delete after full rollout |
| Experiment toggle | Split traffic between variants to measure which performs better | The length of the experiment, then removed |
| Ops toggle | Let operators shed load or disable an expensive path under pressure | Long-lived by design — it is a control, not debt |
| Permission toggle | Give a feature to a plan, a tenant or a group of users | Permanent — this is a product feature, not a release tool |
The first two are temporary and the second two are not. Confusing them in either direction hurts: a release toggle left in place becomes an untested code path that quietly rots, and a permission toggle logged as "flag debt" gets deleted by someone doing cleanup, taking the paid tier with it.
When rollback is not available
Release plans routinely list "roll back" as the mitigation for every risk, and for stateless code that is honest. The moment a release touches persistent data, it usually stops being true — and the plan is now describing a safety net that does not exist.
The reason is simple. If version 2 dropped a column, wrote data in a new shape, or consumed a message from a queue, then going back to version 1 does not restore the world — version 1 now meets data it was never written to handle. Restoring a backup loses everything users did since the deploy. This is why experienced teams plan to roll forward: fix and deploy again, in minutes, rather than reverse.
The technique that keeps both options open is expand and contract. Instead of one migration that changes the shape, you do three releases: expand — add the new column while the old one keeps working and both are written; migrate — backfill and switch reads to the new column; contract — remove the old column once nothing reads it. Each step is individually reversible, and the irreversible one happens last, after the new path has been running in production for days.
What a go/no-go should actually check
Where a release decision genuinely needs a moment of judgement, keep the checklist about the things that are not automatable. Whether the tests passed is not one of them — the pipeline already knows, and asking a room of people to confirm it adds delay without information.
- Is the way back defined — flag off, roll forward, or a rehearsed data path — and has anyone actually done it?
- What signal would tell us within ten minutes that this made things worse, and is somebody watching it?
- Who outside engineering needs to know before users notice — support, sales, the people answering the phone?
- Does anything irreversible happen in this release, and can it be moved to a later one?
- If it goes wrong at the worst plausible moment, who is available and how are they reached?
Measure the process, not the plan
The DORA research found four measures that together predict both delivery speed and stability — and, unusually for this field, showed that the two are not a trade-off. Teams that deploy more often also break things less often, because small changes are easier to reason about and to reverse.
Deployment frequency
How often code reaches production. Elite performers deploy on demand, several times a day.
Lead time for changes
Commit to running in production. Under an hour at the elite level; months at the low end.
Change failure rate
Share of deployments causing a degraded service. Elite teams sit in the low single digits to about 15%.
Time to restore
How long a degraded service stays degraded. Under an hour is the elite benchmark, and it matters more than avoiding failure.
The pairing is the point. The first two describe throughput and the second two describe stability, and reading either pair alone gives a number a team can improve by making the other worse. A fifth measure — some form of reliability, meaning whether the service met the expectations its users actually have — was added later precisely because a team can score well on all four while the product is unusable.
A caveat worth carrying: these are diagnostic, not a scoreboard. Deployment frequency is trivially gamed by splitting one change into five, and a team measured on change failure rate will simply stop calling things failures. Read them together, and read them against your own trend rather than against someone else's benchmark.
How this shows up in real delivery
The clearest signal of release health is what happens on a Friday afternoon. A team that will not deploy on a Friday is telling you something precise: its rollback is slow, its monitoring will not catch a problem quickly, and recovery needs specific people who are about to go home. The fix is not a Friday policy — it is the recovery time underneath it.
Where it degrades
- A release board that approves deployments — it adds delay without adding information the tests did not have.
- Batching a month of changes into one release, which makes every failure hard to attribute.
- "Roll back" written as the mitigation for a release that runs an irreversible migration.
- Feature flags with no owner or expiry, which quietly become permanent branches in the code.
- A canary with no automated comparison, which is a slower big bang with a nicer name.
- Deployment frequency set as a target, which produces more deployments rather than more value.
When to use it
Use it when
- You can deploy to production without a manual gate — otherwise start there.
- Monitoring can tell within minutes whether a change made things worse.
- Product decisions about who sees a feature need to be reversible.
- You want to release to a slice of users and learn before committing.
- Schema changes can be staged so nothing irreversible happens in the same release as new behaviour.
Avoid it when
- Shipped hardware or client software that users install — the release is genuinely one-way.
- A regulated release requiring formal sign-off on a fixed, versioned artefact.
- The team cannot yet remove flags reliably — flag debt will cost more than the flexibility gains.
- There is no monitoring, which makes a canary release just a slower big bang.
Found this useful?
Share it with someone who is working on the same problem.