Deployment Strategies
Every time you ship a new version of your app, you face the same question: how do you replace the old version with the new one without breaking things for the people using it right now? A deployment strategy is simply the plan for how the swap happens — how fast, how risky, and how easy it is to undo if something goes wrong. The three you will meet again and again are rolling, blue-green, and canary. This page explains each one in plain English, shows you when to use it, and ties it back to zero-downtime deploys and quick rollbacks.
The three strategies at a glance
Before the details, here is the comparison most tutorials skip. A rollback (undoing a deploy and going back to the previous version) is the column that matters most when things break at 2am, so pay attention to it.
| Strategy | Risk | Cost (servers/$) | Rollback speed | Complexity | Best for |
|---|---|---|---|---|---|
| Rolling | Medium | Low — reuses the same servers | Slow — must roll back instance by instance | Low | Most apps; small teams; limited budget |
| Blue-green | Low | High — needs two full environments | Instant — flip traffic back | Medium | Apps that need fast, safe rollback |
| Canary | Lowest | Medium — a little extra capacity | Fast — pull the canary | High | High-traffic apps; catching bugs early |
There is no single “best” one. You pick based on how much hardware you can afford and how badly a bad deploy would hurt you.
Rolling deployment
A rolling deployment updates your servers a few at a time instead of all at once. Imagine you have four servers behind a load balancer (a server that spreads incoming requests across several machines). You take server 1 out of rotation, update it, put it back, then do server 2, and so on. At every moment most of your servers are still serving traffic, so users never see an outage.
Diagram in words: Start with [v1] [v1] [v1] [v1]. Update one → [v2] [v1] [v1] [v1]. Keep going → [v2] [v2] [v1] [v1] → [v2] [v2] [v2] [v1] → [v2] [v2] [v2] [v2]. The fleet shifts from old to new gradually.
On a single Ubuntu box running PM2 in cluster mode, a rolling reload is one command:
pm2 reload myapp
Output:
[PM2] Applying action reloadProcessId on app [myapp](ids: [ 0, 1, 2, 3 ])
[PM2] [myapp](0) ✓
[PM2] [myapp](1) ✓
[PM2] [myapp](2) ✓
[PM2] [myapp](3) ✓
When to use it: This is the sensible default. It costs nothing extra because it reuses the servers you already have, and it gives zero downtime. When NOT to use it: rollback is slow — to undo it you have to roll the old version back across every instance the same slow way. And for a while you have both v1 and v2 running at once, so the two versions must be compatible (especially database changes).
Blue-green deployment
A blue-green deployment runs two complete copies of your app side by side. One is blue (the version live right now), the other is green (the new version). You deploy the new version to the idle environment, test it privately, and then flip all traffic over at once by changing where the load balancer points.
Diagram in words: Traffic flows to BLUE (v1) while GREEN (v2) sits ready but private. You test green. Then you flip the switch — now all traffic flows to GREEN (v2) and BLUE (v1) sits idle as your instant fallback.
With Nginx (a reverse proxy — a server that sits in front of your app and forwards requests to it) the “switch” is just an upstream block you re-point:
# /etc/nginx/sites-available/myapp
upstream app_pool {
server 127.0.0.1:3000; # blue (currently live)
# server 127.0.0.1:3001; # green (next release)
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app_pool;
}
}
To cut over, comment out blue, uncomment green, then reload (which never drops a request):
sudo nginx -t
sudo systemctl reload nginx
Output:
nginx: configuration file /etc/nginx/nginx.conf test is successful
Tip: The whole point of blue-green is the instant rollback. If green misbehaves, flip the
upstreamback to blue and reload — you are on the old version in seconds, because blue was never torn down. Keep blue running until you are confident in green.
When to use it: when downtime or a bad deploy is expensive and you want a rollback that takes seconds, not minutes. When NOT to use it: it doubles your running cost because you must keep two full environments alive, and shared resources like a single database still need careful, backward-compatible migrations.
Canary deployment
A canary deployment sends the new version to a small slice of users first — say 5% — while everyone else stays on the old version. You watch the error rate and latency of that slice. If the canary stays healthy, you grow it to 25%, then 50%, then 100%. If it goes bad, you pull it and only a few users were ever affected. The name comes from the canary birds miners carried underground as an early warning.
Diagram in words: 95% → v1 and 5% → v2. Metrics look good → 75% → v1, 25% → v2 → … → 0% → v1, 100% → v2. Bad metrics at any step → send 0% to v2 and stop.
You can do a basic weighted canary in Nginx by giving the new version fewer weight points:
upstream app_pool {
server 127.0.0.1:3000 weight=19; # v1 — ~95% of traffic
server 127.0.0.1:3001 weight=1; # v2 — ~5% (the canary)
}
Reload Nginx to apply, then raise the canary’s weight step by step as you gain confidence:
sudo nginx -t && sudo systemctl reload nginx
When to use it: high-traffic production apps where you want to catch a bad release before it reaches everyone. The blast radius of a failure is tiny. When NOT to use it: it is the most complex option — you need solid monitoring (error rates, latency dashboards) to judge whether the canary is healthy, otherwise you are flying blind. For a small app with little traffic, 5% might be too few requests to tell anything.
How they relate to zero-downtime and rollbacks
All three strategies are built to give zero downtime — at no point is your app fully offline, because there is always a healthy version serving traffic. They differ mainly in how they fail safely:
- Rolling keeps cost low but makes rollback a slow reverse-roll.
- Blue-green spends extra money to buy a near-instant rollback (just flip the switch).
- Canary limits the damage of a bad deploy by exposing it to only a few users first.
Whatever you choose, always pair it with health checks so traffic only reaches instances that are actually ready, and keep the previous version around until the new one has proven itself.
Best Practices
- Default to rolling deployments; only reach for blue-green or canary when the cost is justified by the risk.
- Always make database changes backward-compatible so old and new versions can run at the same time during the rollout.
- Never tear down the old version until the new one has passed health checks and real traffic — that is your rollback.
- Add health checks to every strategy so the load balancer skips instances that are still booting.
- For canary deploys, watch metrics (error rate, latency) before each traffic increase — automate the rollback if they spike.
- Test the green environment privately before flipping traffic in blue-green; that is the whole advantage.
- Practise a rollback in staging so the real one at 2am is muscle memory, not a panic.