What Is Blue-Green Deployment - and When You Actually Don't Need One
Two Production Environments, One Live
Blue-green deployment is a release strategy where you run two complete production environments and only one of them serves traffic at a time. You deploy the new version to the idle one, verify it, then move traffic across in a single switch.
It exists to solve one specific problem: the window during a deployment when your system is half-old and half-new, and neither the old rollback plan nor the new code fully applies.
The switch replaces that window with an instant. If the new version misbehaves, you point traffic back at the environment that was serving five minutes ago, which is still running and still warm.
What that buys you is rollback speed. What it costs you is a second production environment and a hard constraint on how your database schema is allowed to change.
| Concept | Blue-green deployment |
|---|---|
| Where it sits | Release strategy - sits at the traffic-routing layer, in front of your application instances |
| In one sentence | Run two identical production environments, deploy to the idle one, and switch traffic in a single step so rollback is a switch back rather than a redeploy. |
The 60-Second Answer
What it does: keeps two full production environments - blue and green - with only one live. You deploy to the idle one, test it against production dependencies, then flip routing.
The problem it solves: slow, risky rollback. Reverting is repointing traffic at an environment that is already running, not rebuilding and redeploying the previous version under pressure.
The cost it adds: double the production footprint during a release, and every database change must be compatible with both versions at once, because both may be live during the switch.
If your rollback today is "redeploy the previous image, takes 4 minutes, nobody panics", you probably do not need this.
How It Actually Works
The mechanism, step by step
- 1. Two environments exist, only one receives traffic
- 2. You deploy to the idle environment and test it there
- 3. The switch is a routing change, not a deployment
- 4. In-flight requests and connections drain, they do not teleport
- 5. The database is shared, and that constrains your schema changes
- 6. The old environment stays up as the rollback path
- 7. The colours swap roles, and the next release goes the other way
1. Two environments exist, only one receives traffic
The core invariant
Blue and green are full production stacks: application instances, configuration, and whatever runtime state your app owns. A routing layer in front - a load balancer, a DNS record, an ingress, a service mesh route - decides which one the world reaches.
The environments are meant to be identical except for the application version. Any drift between them turns the switch from a controlled event into a discovery exercise.
⚠️ In production — Drift is the failure mode that gets teams the first time. If blue was patched by hand six weeks ago and green was rebuilt from the template, you are not switching versions - you are switching two different unknowns. Both environments must come from the same automation.
2. You deploy to the idle environment and test it there
Verification against real dependencies
The new version goes to whichever environment is not serving traffic. Because it is a real production stack, it can talk to the real database, the real queues, and the real third-party endpoints while zero users are pointed at it.
This is the part staging cannot do. You are testing the artefact you are about to ship against the dependencies it will actually run against.
⚠️ In production — "Zero users" does not mean zero effects. The idle environment can still write to the shared database, consume from shared queues, and fire real webhooks. Decide explicitly which side effects it is allowed to have before the first release, not during one.
3. The switch is a routing change, not a deployment
One atomic-ish operation
Cutover means updating the routing layer to point at the other environment. With a load balancer target group or an ingress rule this takes effect in seconds.
# illustrative: ingress pointing at the live colour
spec:
rules:
- http:
paths:
- backend:
service:
name: app-green # was app-blue
Because it is a routing change, it is fast and it is reversible by making the same change again.
⚠️ In production — Do not use DNS as the switch if you care about rollback speed. DNS is cached by resolvers and clients that ignore your TTL, so a fraction of traffic keeps hitting the old environment for an unpredictable period. Switch at a layer you control end to end.
4. In-flight requests and connections drain, they do not teleport
The switch is not instantaneous for existing work
New connections go to the new environment immediately. Requests already in progress, open WebSockets, long polls and streaming responses continue against the old one until they finish or are closed.
So for a period after the switch, both versions are serving production traffic simultaneously. You plan for that window rather than pretending it does not exist.
⚠️ In production — This is why long-lived connections make blue-green harder than the diagrams suggest. A WebSocket session can outlive several deployments. Either build reconnect logic that tolerates version changes, or accept forcibly dropping those sessions at cutover.
5. The database is shared, and that constrains your schema changes
Where the strategy actually bites
Almost nobody duplicates the production database, because you would then have to reconcile writes made to both copies. So blue and green share one database, which means the schema must work with both versions of the application at once.
The standard discipline is expand-contract: add the new column or table first, deploy code that writes to both shapes, migrate the data, switch, and only remove the old shape in a later release once no running version depends on it.
⚠️ In production — A destructive migration bundled with the release quietly removes your rollback. The moment you drop a column the old version reads, switching back takes the old environment down too, and you have a second production environment that cannot save you.
6. The old environment stays up as the rollback path
Rollback = switch back
After cutover the previous environment keeps running, unchanged and warm. If error rates or latency move the wrong way, you flip the routing back and you are on the previous version within seconds.
That is the whole payoff of the strategy. Rollback does not require a build, a redeploy, or a decision made calmly under pressure.
⚠️ In production — Define the retention window and the rollback criteria in advance - how long the old environment stays, and which metric at what threshold triggers the switch back. Teams that leave both undefined either keep environments running for weeks or tear the old one down twenty minutes before they need it.
7. The colours swap roles, and the next release goes the other way
Alternating, not permanent
After a successful release the newly live environment becomes the reference and the old one becomes the deployment target for next time. There is no permanent "production" and "spare".
This is why automation matters more than the concept. The pipeline has to know which colour is live, deploy to the other, run the checks, switch, and record the result.
⚠️ In production — Store which colour is live in one authoritative place that the pipeline reads, not in someone's memory or a wiki page. Deploying to the live environment because the tracking drifted is the most common way teams take an outage with this strategy.
- A stateless API behind a load balancer. Two target groups, blue and green, each with its own set of instances. Releases are a target-group swap on the listener, and rollback is the same swap in reverse. This is the shape blue-green fits best, because there is no session state stranded on the old instances.
- A containerised service on an orchestrator. Two deployments with distinct labels, one service or ingress selecting between them. The new version runs its full readiness checks while receiving no traffic, and the switch is a selector change. Resource cost is doubled only for the duration of the release, which makes it cheaper than the classic VM version of the same idea.
- A regulated system that requires a tested rollback plan. The value here is less about downtime and more about evidence: at any moment during the release you can name the exact environment that served the previous version and demonstrate that reverting is a single controlled action.
- A release that includes a risky schema change. The team splits it across two releases - expand in the first, contract in the third - specifically because blue-green forces both versions to coexist against one database. The constraint is real work, but it also removes a class of migration failures that only appear at cutover.
When You Actually Need It
- Your current rollback path is "rebuild and redeploy the previous version" and it takes long enough that people hesitate to use it during an incident.
- You can afford to run two production environments simultaneously for the duration of a release, in cost and in quota.
- Your application is stateless, or its state lives in shared services rather than on the instances themselves.
- You control a routing layer that can switch traffic in seconds - load balancer target groups, ingress rules, a mesh route - rather than only DNS.
- Your deployments are automated end to end, including which environment is currently live. Manual tracking cancels most of the benefit.
- Your team already has, or is willing to adopt, expand-contract discipline for database migrations.
When You Don't
- You deploy a single small service a few times a week and rollback is a container image tag change that completes in a couple of minutes. The strategy adds cost and ceremony to solve a problem you do not have - a rolling update is enough.
- You cannot double the production footprint even briefly, because of cost, licensing, or capacity limits. A half-sized green environment is not a valid rollback target, since it has never been proven to carry full load.
- Your application holds meaningful in-memory state or long-lived connections and you are not prepared to drop or migrate them at cutover. Switching traffic will move users mid-session and the strategy will look like it caused the bug.
- What you actually want is gradual exposure - shipping to 5% of users and watching. That is canary deployment, and blue-green is the wrong tool: it is binary by design. Feature flags plus a rolling update get you closer at lower cost.
- Your releases routinely include destructive schema changes and the team is not going to split them across releases. Blue-green will give you the appearance of a rollback path while the database quietly removes it.
What People Get Wrong
"Blue-green deployment means zero downtime."
It removes downtime caused by the deployment itself, not downtime caused by the release. A version that fails under real traffic still fails - the difference is that recovery is a routing switch instead of an emergency redeploy.
"Only one version is ever live, so you never have to think about compatibility."
Both versions serve traffic during connection draining, and both share one database throughout. Backward and forward compatibility is a hard requirement of this strategy, not an optional nicety.
"It is the same thing as a canary release."
Canary shifts a percentage of traffic gradually to limit blast radius. Blue-green moves all traffic at once and limits recovery time instead. They optimise different variables and are sometimes combined, with a percentage switch between the two environments.
"You can roll back at any time after the release."
Only while the old environment is still running and the database still supports it. Once you tear the environment down or run the contract step of a migration, the rollback path is gone and you are back to redeploying.
The Constraint That Forced the Design
Every release strategy is an answer to the same question: what do you do during the interval when the old version and the new version both partially exist?
A rolling update accepts that interval and shrinks it. Instances are replaced a few at a time, so for several minutes some requests hit the old code and some hit the new. That is cheap - you never need more capacity than you already run - but rollback is another rolling update in the opposite direction, at exactly the moment you least want a slow, gradual process.
Blue-green makes the opposite trade. It refuses to mix versions inside one environment, and pays for that with a second full stack. The interval does not disappear; it moves to the routing layer where it lasts seconds instead of minutes, and where reversing it is one operation.
What gets traded away is worth naming precisely. You give up capacity efficiency, since you must be able to run two environments at once. You give up schema freedom, because a shared database serving two application versions cannot accept destructive changes in the same release. And you give up gradual exposure, because the switch is binary - if the new version has a bug that only appears at full traffic, 100% of users find it simultaneously.
That last point is why blue-green and canary keep showing up together. Blue-green gives you a fast, well-defined way back; canary gives you a small, cheap way to find out you need it. Once you see them as answers to different halves of the same question, choosing between them stops being a matter of taste and becomes a matter of which risk your system actually carries.
Related Briefs
What to Read Next
- what is canary deployment
- what is a rolling update
- expand and contract database migration
Blue-green deployment buys one thing: rollback measured in seconds, because the previous version never stopped running. You pay for it with a doubled production footprint and a permanent constraint on how your schema changes. If your existing rollback is fast enough that nobody hesitates to use it mid-incident, you are paying for a guarantee you already have.
댓글
댓글 쓰기