DEV Community

Michael Sun
Michael Sun

Posted on • Originally published at novvista.com

Zero-Downtime Deployments: Blue-Green, Canary, and Rolling Updates Explained

Every minute of downtime has a price tag. Gartner's oft-cited figure of $5,600 per minute is from 2014 — adjusted for today's always-on expectations, the real number for mid-market SaaS sits between $8,000 and $15,000. But the cost that never makes a spreadsheet is user trust. A customer who hits a 502 during checkout doesn't file a support ticket. They leave.

The good news is that zero-downtime deployments are no longer the exclusive domain of teams with dedicated platform engineering. The tooling has matured. The bad news is that "zero-downtime" has become marketing language — the trade-offs, failure modes, and edge cases rarely get covered alongside the pretty diagrams.

The Three Strategies at a Glance

Blue-Green is the oldest and most intuitive. Two identical production environments: one (blue) serves live traffic while the other (green) runs the new version. Flip the load balancer. Instant switchover, instant rollback.

The trade-off is infrastructure cost — you need double the compute sitting idle. And if your app stores sessions in memory (it shouldn't, but many do), the switchover drops every active session. Redis-backed sessions or JWT authentication eliminate this problem before it bites you.

Canary Releases take a more cautious path. Route a small percentage of traffic — say 5% — to the new version and watch error rates, p95 latency, and business metrics. Only if those hold steady do you proceed to 100%. This is the strategy that Google and Netflix champion, and for good reason: canary deployments catch problems that staging environments never surface, like subtle performance regressions under real load or edge cases hiding in user data your fixtures don't cover.

Nginx handles weight-based splitting natively:

upstream app_backend {
    server 10.0.1.10:8080 weight=95;  # Stable
    server 10.0.1.20:8080 weight=5;   # Canary
}
Enter fullscreen mode Exit fullscreen mode

Rolling Updates replace instances one-at-a-time — this is Kubernetes' default strategy. The maxUnavailable and maxSurge parameters control how aggressive the rollout is. The key requirement is that both the old and new version can run simultaneously against the same database schema. That constraint surfaces the hardest part of zero-downtime deployments: database migrations.

The Problem Nobody Leads With

All three strategies share the same underlying challenge: during any deployment, old and new application code run concurrently against the same database. Add a NOT NULL column, rename a field, or drop a table — and you've just broken every instance still running the old code.

The expand-contract pattern is the answer. Instead of one breaking change, you make three non-breaking ones: add the new structure alongside the old (expand), deploy code that writes to both, then drop the old after the migration is complete (contract). It takes more deployments. It is the only reliable approach.

Three Key Takeaways

  1. Choose the strategy that matches your infrastructure reality. Blue-green requires double compute. Canary requires robust observability. Rolling updates require schema backward compatibility. Pick the trade-off you can actually sustain.

  2. Observability is a prerequisite, not a nice-to-have. Canary deployments are only valuable if you're watching the right metrics: not just error rates, but p99 latency, business conversion, and resource consumption on new instances.

  3. The database is the hard part. Any zero-downtime deployment strategy is undermined by schema changes that break the running application. Treat migrations as a separate, careful process — never as an afterthought bundled into the same deployment.


Read the full article at novvista.com for complete Nginx, HAProxy, and Kubernetes configuration examples, plus a detailed breakdown of when each strategy makes sense for your team size and infrastructure.


Originally published at NovVista

Top comments (0)