Choosing how to roll out a release
Open in the interactive app: practice, quiz, mock interview →In one minute
- A deployment strategy decides how a new version replaces the old one: all at once (recreate), a few instances at a time (rolling), a whole parallel fleet and one switch (blue-green), a small slice of traffic first (canary), or a copy of traffic with no user impact (shadow).
- Every strategy is a choice along four axes: blast radius (how many users a bad build can hurt before you notice), rollback time, capacity overhead, and version mixing (whether old and new run side by side).
- Large organisations combine them: build once, deploy to one box, then one cell or zone, then progressively wider waves, with automated health gates and bake time between waves.
- Configuration, feature flags, schemas and ML models are deployments too. Several of the biggest outages in recent years came from config pushed everywhere at once.
- The strategy only works if the release is compatible both ways: new code with old data and old code with new data, because every non-recreate strategy runs both at once.
How it works
The menu
Recreate. Stop every old instance, then start the new ones. No extra capacity and no version mixing, but downtime equals startup time and every user meets the new version at once. Kubernetes calls it strategy: Recreate; it fits batch workers and software that cannot run two versions against the same state.
Rolling. Replace instances in batches: start a few new ones, wait for readiness, remove a few old ones, repeat. Kubernetes' default RollingUpdate uses maxSurge and maxUnavailable (25% each by default) (Kubernetes docs). It needs little spare capacity, but each batch meets real traffic uncompared, and rollback is another full rolling deploy. The rolling deployments lesson covers the mechanics.
Blue-green. Stand up a complete second fleet with the new version, test it against production dependencies, then flip all traffic in one routing change. Rollback is the same flip, in seconds, as long as the old fleet is still running. The cost is double capacity during the release, and the flip still exposes every user at once. See blue-green deployments.
Canary. Route a small percentage of traffic, say 1%, to the new version, compare its error rate and latency against a baseline, and widen in steps (1%, 10%, 50%, 100%) only while it stays healthy. Blast radius is tiny and rollback is a weight change, but the rollout is slow and the analysis must be statistically sound. See canary releases.
Shadow (dark launch). Mirror real requests to the new version and discard its responses, comparing them with the live version's output. Users are never affected, so it suits rewrites, new databases and new models. It cannot test side effects unless writes are stubbed, and it doubles downstream load.
Feature flags. Ship the code dark and turn behaviour on per user, per percentage or per tenant at runtime. Flags separate deploy from release, so the deploy itself can be boring. See feature flags.
Combining them: waves and cells
At scale, the question shifts from "which strategy" to "in what order do we expose the fleet". Amazon's published practice deploys to one box first, then one availability zone, then one region, then progressively larger waves of regions, with automated rollback on alarm and a bake time at each stage that gives slow failures (memory leaks, daily batch jobs, certificate expiry paths) a chance to show up. The numbers are deliberately slow: the one box serves at most about 10% of a region's or zone's requests and bakes for at least an hour, the first region bakes for at least 12 hours, later waves for 2 to 4 hours, and bake time also waits for a minimum count of requests. With default settings a change takes about four or five business days to reach every region, and deployments skip nights, weekends and holidays when on-call engineers are slower to respond (AWS Builders' Library). Microsoft's guidance is similar: bake times measured in hours and days, growing with each ring (Azure Well-Architected). Inside each wave, a rolling or blue-green mechanism does the actual replacement. Cell-based architectures make this cleaner: each cell is an independent copy of the stack serving a fixed slice of customers, so a wave is a set of cells and blast radius is literally the share of customers in those cells.
Problem shape: partial failure and blast radius
Google's SRE team found that roughly 70% of outages come from changes to a live system (Google SRE book, ch. 1), so the rollout is where most risk lives. Choosing a strategy is a way of bounding partial failure. The same reasoning applies to rolling out a new prompt or model in an AI product: shadow it on logged traffic, canary it to 1% of conversations, compare quality metrics against the incumbent, and keep the old model loaded so rollback is a routing change rather than a redeploy.
Down the stack
Layer 1The contract
A deployment strategy's contract can be written as four numbers per release. Exposure: the fraction of traffic served by the new version before the first health gate is evaluated (recreate and blue-green: 100%; rolling: one batch; canary: the first step). Detection-to-rollback time: from an alarm firing to all traffic on the old version (canary and blue-green: one routing update; rolling and recreate: a redeploy). Capacity overhead: peak instances relative to steady state (recreate 1x, rolling 1x plus surge, blue-green and mesh-weighted canary up to 2x). Mixed-version window: how long both versions serve at once (zero for recreate; the whole rollout for rolling and canary; the drain period for blue-green). A good release process states these numbers up front.
Layer 2The mechanism
Where the switch lives decides how fast it moves. DNS weights and records are cached by resolvers and clients for at least the TTL, and some clients ignore TTLs entirely, so a DNS cutover drains over minutes to hours. Load balancer changes, such as re-weighting AWS ALB target groups, apply to new connections within seconds. Service mesh routing (Istio VirtualService weights, Envoy weighted_clusters) splits per request, which allows 1% canaries. The Kubernetes Gateway API gives the same split in a vendor-neutral form: an HTTPRoute lists backendRefs with proportional weights such as 90 and 10 (Gateway API). Envoy's request_mirror_policies implement shadow traffic: mirroring is fire-and-forget, Envoy does not wait for the shadow, and it appends -shadow to the Host header so the shadow service can tell copies apart (Envoy docs). Managed platforms now ship these strategies too: Amazon ECS added built-in blue/green and, in October 2025, built-in linear and canary deployments with bake times and lifecycle hooks (AWS). Orchestrators encode the strategy declaratively: Kubernetes Deployments support Recreate and RollingUpdate, and controllers such as Argo Rollouts or Flagger add blueGreen and canary strategies with analysis steps that query Prometheus and abort automatically. In-process, a flag SDK evaluates rules from a locally cached ruleset.
A health gate is a function from metrics to a verdict: wait, proceed or roll back. It compares the new version against a baseline running the old version at the same time (not against last week), and it needs a minimum request count before it can judge anything. Google's canary guidance puts that floor at about 50 data points per metric for the statistical tests to mean anything, which at one-minute resolution can stretch an analysis to hours (Google Cloud).
Layer 3The machine
Deploy speed is dominated by startup, not routing. Pulling a 1 GB container image at 100 MB/s takes 10 seconds per node unless it is cached; a JVM service may need 30 to 90 seconds of JIT warm-up before its latency matches the old fleet, which can fail a naive canary on p99 latency even when the code is fine. Empty in-process caches send a burst of misses to the database for the first minutes, so a blue-green flip of a large fleet can briefly double database load. Removing old instances needs connection draining: the load balancer stops new requests, in-flight requests finish, HTTP/2 servers send GOAWAY, and only then does the process exit, often after a preStop sleep of a few seconds so endpoint removal propagates to every proxy. Long-lived connections (WebSockets, gRPC streams) do not move on a routing change at all until they reconnect, so "100% switched" at the balancer can still mean thousands of clients on the old version.
Why it's built this way
- Tests cannot reproduce production traffic, data and dependencies, so some failures only appear when real users hit the new version.
- If failures will reach users anyway, the controllable variable is how many users and for how long, which is exposure times detection time.
- Fast rollback needs the old version still running, which costs capacity; slow rollback is cheap but extends every incident, so strategies trade money for recovery time.
- Some failures are slow (leaks, daily jobs, rare paths), so gates add bake time, and wide fleets deploy in waves so a slow failure stays contained to the early waves.
- Running two versions at once is unavoidable for zero-downtime strategies, so compatibility between versions becomes a requirement of every change.
Diagram
flowchart TD
Q1{"Can two versions run at once?"} -->|"no"| RC["Recreate (accept downtime)"]
Q1 -->|"yes"| Q2{"Need rollback in seconds?"}
Q2 -->|"no"| RO["Rolling update"]
Q2 -->|"yes"| Q3{"Can afford 2x capacity briefly?"}
Q3 -->|"no"| RO
Q3 -->|"yes"| Q4{"Need small blast radius?"}
Q4 -->|"no"| BG["Blue-green flip"]
Q4 -->|"yes"| CA["Canary with health gates"]
CA --> W["Wider waves: zone, region, all"]Worked example
A checkout service runs 40 instances across three zones and serves 6,000 requests per second. New instances take 90 seconds to pull, start and warm up. The team deploys twice a day and wants a bad build to cost fewer than 1,000 failed checkouts.
Suppose a bad build fails 20% of requests and alarms fire 3 minutes after the bad version starts serving.
Recreate. Every deploy causes 90 seconds of downtime: 540,000 failed requests, before the build is even known to be bad. Ruled out.
Rolling, batches of 4. The first batch serves 10% of traffic, 600 requests per second, 120 of which fail. In the 3 minutes to detection that is 21,600 failures, and the rollout has meanwhile moved on to more batches unless each batch bakes. Rollback is another rolling deploy, about 10 batches of 90 seconds each, 15 minutes. Far above budget.
Blue-green. 40 extra instances for the release window, about 30 minutes per deploy including bake, so 1 hour a day of double capacity. Detection still happens with 100% exposure: 1,200 failures per second for 3 minutes is 216,000. Rollback takes 5 seconds, but the exposure already blew the budget.
Canary at 1%, then 10%, 50%, 100%, with 10-minute bakes. At 1%, 60 requests per second hit the new version and 12 fail. A gate with a minimum of 3,000 canary requests can judge after 50 seconds; with a 2-minute evaluation window, about 1,440 failures in the worst case. Tightening the first gate to abort when the canary's error rate exceeds twice the baseline after 1,500 requests (25 seconds) brings it under 400. Rollback is a weight change. The cost is a rollout of about 45 minutes and a few spare instances during the early steps.
The team picks canary with automated gates for code, keeps blue-green for runtime upgrades, and puts risky features behind flags.
In the wild
- Cloudflare, 2019: a rule change that skipped the staged rollout. A new WAF rule with a regex that backtracked catastrophically went to the whole network in seconds, because WAF rules were shipped globally rather than through the staged path used for code. A CPU safeguard had been removed by mistake in an earlier refactor, so every core pegged and about 80% of traffic failed for 27 minutes. Cloudflare restored the safeguard, reviewed all 3,868 rules and added staged rollouts for rules (Cloudflare).
- Google Cloud, 2025: global data reaches unflagged code. A Service Control code path added on 29 May had no feature flag and no error handling. On 12 June a quota policy with blank fields replicated worldwide within seconds and crash-looped API frontends in every region. A kill switch went out after about 40 minutes, but restarts without randomised backoff overloaded Spanner in us-central1 and stretched recovery to hours. Google committed to flag-gating critical changes and rolling out globally replicated data incrementally (Google Cloud).
- Cloudflare, 2025: a generated config file pushed network-wide. A ClickHouse permissions change made a query return duplicate rows, doubling the Bot Management feature file that is rebuilt every five minutes and pushed everywhere. It exceeded a 200-feature limit and the proxy panicked, so core traffic largely failed for about three hours, flapping as good and bad files alternated. Cloudflare said it would treat internal config like user input and add global kill switches (Cloudflare).
Trade-offs
| Strategy | Strengths | Weaknesses | Choose when |
|---|---|---|---|
| Recreate | Simplest, no mixing, no extra capacity | Downtime, full exposure | Batch workers, dev, incompatible versions |
| Rolling | Little extra capacity, built into orchestrators | Slow rollback, uncompared exposure per batch | Stateless services with good readiness checks |
| Blue-green | Rollback in seconds, test the full new fleet first | 2x capacity, full exposure at the flip | Infrastructure changes, few releases a day |
| Canary | Tiny blast radius, metric-driven progression | Slow, needs traffic volume and good metrics | High-traffic user-facing services |
| Shadow | Zero user impact, real load and inputs | No side effects tested, doubles downstream load | Rewrites, new datastores, new models |
| Feature flags | Release without deploy, per-user control | Flag debt, combinations to test | Product features, kill switches |
Pitfalls in production
- Config deployed outside the pipeline. Code goes through canaries while a config change, rules file or flag flips globally in seconds. Route config through the same staged rollout with gates and bake time.
- Gates that compare against the past. Comparing a canary with yesterday's error rate confuses traffic patterns with regressions. Compare against a baseline group on the old version running at the same time.
- Warm-up failing healthy builds. Cold JIT and caches make every new version look slower at first, and teams learn to ignore the gate. Exclude a warm-up period or warm instances with synthetic traffic before they join.
- Incompatible schema changes. A migration that drops a column breaks the old version during a rolling or canary deploy and makes rollback impossible. Use expand and contract: add, deploy readers, backfill, then remove in a later release.
- Slow failures outrun the bake. A leak that takes six hours to exhaust memory passes a 10-minute bake on every wave. Stretch bake time on the first production wave and watch resource trends, not just error rates.
Leadership lens
- Ask for the four numbers on every service: exposure before the first gate, detection time, rollback time and capacity overhead. Their product is the expected damage of a bad release.
- Standardise on one rollout controller and one gate definition across teams; bespoke deploy scripts are where unsafe shortcuts hide.
- Treat config, flags, schemas and models as deployable artifacts with the same staged rollout. Global instant pushes are the largest remaining blast radius in most organisations.
- Invest in deploy frequency. Small, frequent changes make each canary easier to judge and each rollback cheaper, which pays back the slower per-release pipeline.
Check yourself
Why does blue-green give fast rollback but not a small blast radius?
Show answer
The old fleet stays running, so rollback is one routing change. But the flip moves all traffic at once, so every user meets the new version before any production signal exists.
A canary fails its latency gate on every release, and the problem disappears after ten minutes. What is likely happening, and what is the fix?
Show answer
Fresh instances are cold (JIT, caches, connection pools) while the baseline is warm. Warm the canary before measuring, exclude a warm-up window, or compare against freshly started baseline instances.
Why are database schema changes a constraint on every zero-downtime strategy?
Show answer
Rolling, canary and blue-green all run old and new code against the same database at some point, so each schema state must work with both versions, which forces expand-and-contract migrations.
When is shadow traffic better than a canary?
Show answer
When the change has no user-visible side effects to test, but a failure would be costly, such as a new storage engine or a rewritten pricing service. Shadowing compares outputs on real traffic without exposing anyone.
Sources and further study
Primary
- Google SRE book, ch. 1: Introduction: the observation that about 70% of outages come from changes, and why progressive rollouts follow.
- Google Cloud: Service Control incident report (June 2025): what happens when data skips the rollout path that code follows.
Systems docs
- Kubernetes Gateway API: traffic splitting: weighted
backendRefsfor canary and blue-green without a vendor mesh. - Envoy route configuration:
weighted_clustersandrequest_mirror_policies, the mechanisms under most meshes. - Amazon ECS blue/green deployments: bake time, lifecycle hooks and test traffic as managed features.
Books
- The Site Reliability Workbook, Beyer et al., chapter 16 "Canarying Releases": release velocity versus reliability and how canaries fit release engineering.
- Release It! (2nd edition), Michael T. Nygard, chapter 13 "Design for Deployment": the fallacy of planned downtime and the phases of a zero-downtime deploy.
- Building Microservices (2nd edition), Sam Newman, chapter 8 "Deployment": principles of microservice deployment and the options for running them.
Other curricula
- Azure Well-Architected: safe deployment practices: progressive exposure, health models and bake times in hours or days, plus an emergency path for hotfixes.
- roadmap.sh System Design: covers Deployment Stamps as a cloud pattern but has no node on rollout strategies.
Watch
- Top 5 Most-Used Deployment Strategies (ByteByteGo): a quick comparison of the main strategies side by side.
- Kubernetes Deployment Patterns: rolling updates, canary and blue/green (Appsbroker Academy): the same strategies shown on a real cluster.
Free resources
- Automating safe, hands-off deployments (AWS Builders' Library): one-box, waves, bake time and automatic rollback at Amazon scale.
- Canarying releases (Google SRE Workbook): how to pick canary size, duration and metrics, and why to compare against a concurrent control.
- Kubernetes Deployments:
RecreateandRollingUpdate, surge and unavailability settings. - Argo Rollouts concepts: blue-green and canary strategies as a Kubernetes controller, with analysis steps.
- BlueGreenDeployment (Martin Fowler): the original short description of the pattern and its database caveat.