Home › High-Level Design › Deployment Strategies: Blue-Green and Canary
D

Deployment Strategies: Blue-Green and Canary

Shipping code is the single most common way a healthy system breaks. Most outages are not traffic spikes or dead hardware. They are someone pushing a bad version. The whole topic comes down to one lever: how you release decides whether a bug hits 100% of users or 1% of them.

High-Level DesignIntermediate11 min read

If you remember five things

The whole answer in one glance. Everything below defends these five calls.

  1. Same question, two answers. Both strategies ask how to cut over without betting the business on the new code being correct.
  2. Blue-green is a flip. Two full environments, instant switch, instant rollback, but 100% of users feel a bad deploy at the flip, and you pay 2x infra.
  3. Canary is a dial. Start at 1%, watch real metrics, ramp slowly. Tiny blast radius and near-1x cost, but slow to full rollout and it needs automation watching.
  4. The database is the real problem. Both versions share one store. Breaking schema changes are what turn a "fast rollback" into a disaster. Expand-contract, always.
  5. Rollback is only instant for stateless layers. You cannot un-charge a card or un-send an email. Stateful changes need reconciliation, not a flip.

1The core idea#

Start with the mental model. You have a version serving real users, and you want to replace it. The scary moment is the switchover, because a broken new version broadcasts that breakage.

The shared question. Blue-green and canary are two answers to one thing: how do I cut over without betting the whole business on the new code being correct?

Blue-green keeps two full environments.

  • Blue is the current live version taking all traffic.
  • Green is the new version, fully deployed and warmed up, taking zero real traffic.
  • You test green in isolation, then flip a switch (load balancer or DNS) and all traffic moves to green at once.
  • Blue stays alive and idle. If green misbehaves, you flip back in seconds because blue never went anywhere.

Canary is gradual.

  • Deploy the new version alongside the old, then send it a tiny slice of traffic first. Think 1%.
  • Watch error rates, latency, and business metrics.
  • If it looks healthy, bump to 5%, then 25%, 50%, 100%, pausing to observe at each step.
  • The name is the coal-mine canary: a small thing that dies first so the miners get a warning.
1% vs 100%
The one difference that mattersCanary caps how many users see a bug at any moment. Blue-green flips everyone at once and bets on an instant rollback. Everything else in this guide is a consequence of that single choice.
The one-line difference

Blue-green is a binary all-or-nothing flip with instant rollback. Canary is a slow dial that limits how many users see a bug at any moment. Say this first in an interview, then spend your time on the trade-offs.

2How it works#

Both strategies need the same foundation: a routing layer that controls which users hit which version. That is almost always a load balancer, a service mesh, or sometimes DNS.

Blue-green mechanics: two complete stacks, one clean cutover.

flowchart LR A[Client] --> B[Load Balancer] B -->|active| C[Blue v1] B -.->|idle| D[Green v2] C --> E[(Database)] D --> E
The load balancer points at blue. Green is deployed and health-checking but takes no real users. Notice both versions talk to the same database. That shared store is the hardest part of blue-green, covered in the pitfalls.
  • Green runs health checks and maybe synthetic test traffic, but no real users.
  • You run smoke tests against green directly.
  • When they pass, you change one config value and the arrow flips: all traffic goes to green, blue becomes the idle standby.

Canary mechanics: a weighted split you adjust over time.

flowchart LR A[Client] --> B[Load Balancer] B -->|99 percent| C[Stable v1] B -->|1 percent| D[Canary v2] C --> E[(Database)] D --> E
The load balancer sends 1% of requests to the canary and 99% to stable. There is no flip, just a dial you turn up as the signal stays clean.

A real rollout steps up over time, and a tool drives it.

sequenceDiagram participant O as Operator participant LB as Load Balancer participant M as Metrics O->>LB: send 1 percent to canary LB->>M: report errors and latency M-->>O: healthy O->>LB: raise to 25 percent LB->>M: report errors and latency M-->>O: healthy O->>LB: raise to 100 percent O->>LB: retire old version
The canary loop. Each step raises the slice only after metrics come back healthy, and the last step retires the old version.
  • Nobody sits clicking buttons. Argo Rollouts, Flagger, or Spinnaker automate the stepping and, more importantly, the automatic rollback.
  • You define a threshold (say error rate under 0.5% and p99 latency under 300ms) and the system rolls back on its own if the canary breaches it, no human paged at 3am.
From the interviewer's chair

When I ask "which users get the canary," I want to hear the sticky-routing answer. Random per-request routing is simplest, but one user can bounce between versions, which breaks when the versions behave differently. Sticky routing by user ID or session keeps each user on one version. Candidates who name that unprompted have actually run a canary.

3A worked example: rolling out a payments API#

"1% canary" means nothing until you do the arithmetic, so make it concrete.

The setup.

  • A payments API serving 20,000 requests per second, which is 1.2 million requests per minute.
  • SLO: error rate under 0.5% and p99 latency under 300ms.
  • You are shipping a change to the fraud-scoring path, and it has a bug that rejects 3% of legitimate charges.

Blue-green math.

  • You run 200 instances in blue. Going blue-green means standing up 200 more in green, so you pay for 400 instances during the deploy, a clean 2x.
  • Warm green for 10 minutes with mirrored traffic, run smoke tests, flip at the load balancer in about 2 seconds.
  • The 3% bug now hits 100% of users instantly: at 20,000 rps that is 600 failed charges per second.
  • On-call sees the alarm and flips back to blue, say 90 seconds from flip to rollback.
  • Blast: roughly 54,000 wrongly rejected charges in that window.

Canary math.

  • Put 1% on the canary: 200 rps, about 2 instances' worth, so infra during deploy is 202 instances, roughly 1.01x instead of 2x.
  • The 3% bug now affects 6 failed charges per second, and only on the 1% slice.
  • Automated analysis watches the canary's checkout-success-rate against stable, sees it drop from 99.4% to 96.4%, and auto-rolls-back after a 5-minute bake, before you ever reach 5%.
  • Blast: roughly 1,800 wrongly rejected charges, fix shipped with no human touching it.
Winner for this API
Canary
Bad charges
~1,800, contained to the 1% slice.
Infra cost
~202 instances, about 1.01x.
Rollback
Automated, before reaching 5%.
Cost
Slow: ~45 minutes to reach 100% if healthy.
Faster, riskier
Blue-green
Bad charges
~54,000, 100% of users at the flip.
Infra cost
400 instances, a clean 2x.
Rollback
Human in the loop, ~90 seconds.
Cost
Fast: 100% in seconds, trivially reversible.

The signal is trustworthy fast.

  • 1% of 1.2M requests per minute is still 12,000 requests per minute. That is a huge statistical sample.
  • This is why high-traffic companies love canary: the slice is tiny as a fraction but enormous in absolute terms.

4Trade-offs#

This is where interviews actually live. Neither strategy is "better." They optimize for different things.

Dimension Blue-Green Canary
Rollback speed Instant, flip back to blue Fast, dial traffic back down
Blast radius of a bad deploy 100% of users at the moment of flip Only the canary slice, e.g. 1%
Infra cost 2x, you run two full environments ~1x plus a small canary footprint
Time to full rollout Minutes Minutes to hours, sometimes days
Catches slow-burn bugs Weakly, you flip fast and may miss them Strongly, you observe real traffic over time
Operational complexity Lower, it's a switch Higher, needs metrics and automation
Good for stateful changes Harder, two versions share state Also hard, same problem

Blast radius versus rollout speed is the sharpest trade.

  • Blue-green flips everyone at once, so a test miss hits 100% of users for the handful of seconds until you flip back. The instant flip-back is the saving grace.
  • Canary never exposes more than your current step, so a bug that slips tests only hits 1% while you watch. The cost is that it is slow, and a human or a metrics pipeline has to actually be watching.

Cost is the other big one.

  • Blue-green doubles your compute during a deploy: 400 instances instead of 200 in the worked example. On a large fleet that is real money.
  • Canary adds only a few extra instances, 202 in the same example, so it is much cheaper on infra.
Pause before you read on: a memory leak takes 20 minutes to matter under real load. Which strategy catches it, and why?
Reveal the answer
Canary. Blue-green flips to green, your smoke tests pass in the first minute, you move on, and the leak surfaces an hour later with everyone already on green. Canary keeps the new version under real load long enough for slow problems to appear while most users are still on stable. Blue-green barely helps with bugs that only show up under sustained real traffic, and naming that gap is what separates a senior answer from a textbook one.

5Where it is used#

Blue-green shines for clean, auditable, reversible cutovers when you can afford the double infra.

  • Major framework upgrades, a runtime bump, or a release where "all users on the same version" matters for consistency.
  • Common in regulated environments where you want a known-good version sitting ready at all times.
  • A comfortable fit when deploys are infrequent but high-stakes.

Canary is the default for high-traffic consumer services that deploy many times a day.

  • At millions of requests, even a 1% slice is a statistically meaningful sample, so you get fast, trustworthy signal.
  • 1% of a billion requests is still ten million requests, plenty to catch a regression.
  • The natural match for microservices where you deploy one service at a time and want tight blast-radius control.

A pattern I like: use both.

  • Blue-green for the infrastructure-level switch, with a canary-style gradual ramp inside the green environment before you send it everything.
  • You get instant rollback plus graduated exposure.

Feature flags are a cousin worth naming.

  • They operate at the application layer, not the deployment layer.
  • You ship the code to everyone dark, then turn the feature on for 1% of users via config.
  • This decouples "deploy the binary" from "release the feature," a genuinely powerful separation.
  • Mature teams run all three: blue-green or rolling for the binary, canary for the rollout, feature flags for the feature.

6Common pitfalls and gotchas#

The database is the real problem.

  • Both diagrams showed two app versions sharing one database, and that is the honest picture.
  • New code often wants a schema change. If green adds a column and you flip, then flip back to blue, blue may not understand the new schema.
  • Fix is expand-contract: deploy a schema both versions can read and write (expand), deploy the new code, then later remove the old columns (contract) once no version needs them.
  • Never ship a breaking schema change in the same release as the code that depends on it. This one rule prevents a huge class of rollback disasters.

Rollback is not free if state changed.

  • You can flip app servers back in seconds. You cannot un-send an email, un-charge a card, or un-write a row the new version already persisted in a new format.
  • In the payments example, the 1,800 wrongly rejected charges do not un-reject themselves on rollback. Someone has to reconcile them.
  • "Instant rollback" is only instant for stateless layers. Say so in an interview, it shows maturity.

Cold caches and cold JVMs.

  • When you flip to green, its caches are empty and its connection pools are cold. Latency can spike for a few minutes even though nothing is "wrong."
  • This is exactly why the worked example warmed green for 10 minutes with mirrored traffic before the flip.
  • Warm the new environment first, or your clean deploy will look like an incident.

Canary sample bias.

  • Route canary traffic to only one region or one user segment and your 1% is not representative.
  • A canary that only sees North American daytime traffic tells you nothing about the batch job that runs in Asia at midnight.
  • Make the slice random and representative.

Watching the wrong metrics.

  • Error rate and latency are table stakes, but some bugs are silent: a checkout button that renders fine but submits the wrong price.
  • A canary that only watches CPU and 500s will happily promote a revenue-destroying bug.
  • In the payments example, the signal that caught the bug was checkout-success-rate dropping from 99.4% to 96.4%, not a spike in 500s. Watch business metrics too.

Forgetting to actually retire the old version.

  • With blue-green, teams flip to green and leave blue running "just in case" for weeks, paying double.
  • In the example that is 200 idle instances burning money.
  • Set a clear window, verify, and tear down.
Red flag that fails you here

Designing a beautiful system, then hand-waving "and we deploy it" with no mention of schema, rollback of state, or metrics. If you claim "instant rollback" on a payments service and never flag that rejected charges do not un-reject, I have learned you have never watched a rollout go wrong at 3am.

7How it shows up in interviews#

When I ask about deployment in a system design round, I am checking whether you think about failure, not just the happy path. A lot of candidates design a beautiful system and then hand-wave the release. That is the gap I am probing.

Weak answer:

"Blue-green has two environments and canary is gradual. I'd probably use blue-green so I can roll back fast."

  • True on the definitions, but a textbook recital.
  • Names no metric, ties the choice to nothing, and misses that a payments bug hits 100% of users at the flip.
  • This tells me you memorized the terms but never ran a rollout that went wrong.

Strong answer:

"This is a payments API doing about 20,000 requests per second, so I'd canary, not blue-green. I'd start at 1%, which is still around 12,000 requests per minute, enough signal to trust. I'd gate promotion on error rate under 0.5%, p99 under 300ms, and critically on checkout-success-rate compared against the stable fleet, because a fraud-model regression shows up as rejected legit charges long before it shows up as 500s. Automatic rollback via Argo Rollouts if any threshold breaches during a 5-minute bake. I'd avoid blue-green here mainly because a bad flip hits 100% of charges at once, and the 2x infra, roughly 400 instances, buys me a fast rollout I don't actually need for a service that can ramp over 45 minutes. One caveat: rollback doesn't undo charges already rejected, so I'd pair this with reconciliation on the payments ledger."

  • Picks a strategy and justifies it with the specific situation.
  • Names real metrics and thresholds, does the blast-radius math out loud, and flags the stateful-rollback limit.
  • That is staff-level reasoning.

Tie the deployment choice to the system's requirements, not to habit. The signal the interviewer wants is that you read the room.

Follow-ups the interviewer will ask (and your answers)
"How do you roll back?"
Flip app servers back in seconds for the stateless path. But I'd call out that stateful changes don't roll back cleanly: you can't un-charge a card or un-write a row already persisted in a new format. Those need reconciliation, not a flip. Saying that unprompted is the whole point of the question.
"What about the database schema?"
Expand-contract. First deploy a schema both the old and new code can read and write (expand), then deploy the new code, then later drop the old columns once no version needs them (contract). Never ship a breaking schema change in the same release as the code that depends on it, or a rollback leaves the old version unable to read the store.
"How do you decide the canary is healthy?"
Specific metrics and automated thresholds, not "it looks okay." Error rate under 0.5%, p99 under 300ms, and a business metric like checkout-success-rate compared against the stable fleet over a bake window. A tool like Argo Rollouts or Flagger promotes or auto-rolls-back on those thresholds so no human is in the loop at 3am.
"What's the cost of your approach?"
Blue-green's 2x infra should come up unprompted: 400 instances instead of 200 in the worked example, running two full environments during the deploy. Canary adds only a few extra instances, about 202, so it's much cheaper, which is part of why I'd pick it for a large fleet.
"Would you ever combine strategies?"
Yes. Blue-green for the infra-level switch with a canary-style ramp inside the green environment, so I get instant rollback plus graduated exposure. And I'd decouple deploy from release with feature flags: getting the binary onto servers and exposing behavior to users are two separate risks, each worth controlling on its own.

What you can now explain in the room

  • Why blue-green is a flip with instant rollback and canary is a dial that caps blast radius.
  • How to do the blast-radius math: 54,000 bad charges at a flip versus 1,800 on a 1% canary slice.
  • Why 1% of a high-traffic service is still a huge, trustworthy sample (12,000 requests per minute).
  • Why the shared database, not the app tier, is the hardest part, and how expand-contract fixes it.
  • Why "instant rollback" only holds for stateless layers, and when you need reconciliation instead.
  • How to pick a strategy from the system's requirements, and why feature flags decouple deploy from release.

For a worked example, see the System Design Question walkthrough on designing a CI/CD pipeline with safe, automated rollouts.

Get a prep plan built around your Deployment Strategies: Blue-Green and Canary interview

Tell us the role and your interview date. We will send back a dated, day by day plan. Free.

Thanks. Check your inbox, your Deployment Strategies: Blue-Green and Canary prep plan is on the way.