"We deploy at midnight to be safe" is a confession, not a strategy. Zero-downtime deploys are within reach of any team - the concepts are simple once separated from vendor jargon.
The three patterns
Rolling: replace instances a few at a time behind a load balancer - the default in Kubernetes and most PaaS platforms. Blue-green: run the new version alongside the old and switch traffic in one atomic move; instant rollback by switching back. Canary: send 5% of traffic to the new version and watch error rates before ramping to 100%.
- Rolling: simplest, fine for most apps
- Blue-green: best rollback story, doubles infra briefly
- Canary: safest for high-traffic products, needs good metrics
The database is the hard part
During a deploy, old and new code run simultaneously - both must work against the same schema. The rule: make migrations additive first (add the column, backfill, deploy code that writes both, then remove the old one in a later release). Never rename or drop in the same release that changes code.
Health checks make it automatic
A deploy is only zero-downtime if traffic shifts when the new version is actually ready. Expose a health endpoint that verifies dependencies, and configure the platform to wait on it. Pair with drain timeouts so in-flight requests finish before old instances die.
Practice the rollback
A rollback you've never rehearsed is a rumour. Make it one command, and run that command in staging monthly. Confidence, not tooling, is what actually lets teams deploy on Friday afternoon.