Zero-Downtime Deployment Checklist for Production Releases
Checks for reducing deployment interruptions: readiness probes, graceful shutdown, compatible database migrations, traffic management, and rollback verification.
Deployment interruptions can occur during startup, shutdown, schema changes, or traffic switching. Verify each part under representative load before claiming that a release completes without downtime.
Zero-Downtime Deployment Checklist
Pre-Deploy: Application Readiness
Readiness probe configuration
- The
/healthor/readyendpoint returns a non-200 status until the application is fully initialized — not just started - The readiness probe waits for database connections, cache warmup, and any async initialization before returning healthy
- The probe has a realistic
initialDelaySecondsvalue based on observed startup time, not a guess - Traffic is not routed to a new instance until the readiness probe passes
Graceful shutdown
- The application catches
SIGTERMand stops accepting new requests immediately - In-flight requests have a measured drain window before process exit
- The
terminationGracePeriodSecondsvalue is longer than your longest expected request duration - Long-running background jobs are paused or handed off, not killed mid-execution
Pre-Deploy: Database Migrations
Review migration locks and compatibility with every application version that may run during the release.
- Migration sequencing keeps the schema compatible with the old and new application versions during rollout and rollback
- Each schema operation’s lock behavior is understood and tested; any online migration tool is appropriate for the database engine
- Migrations are run before the new application version starts receiving traffic, not after
- A tested recovery plan covers schema changes, including any migration that cannot be safely reversed
- Column transitions include any backfill and compatibility period needed before the old column is removed
Deploy: Traffic Management
- The load balancer removes an instance from rotation before the new version starts deploying to it
- Connection draining is enabled — existing connections complete before the load balancer stops sending to the old instance
- The new instance is added to rotation only after passing the readiness probe
- The deploy is staged — not all instances are updated simultaneously
Deploy: Kubernetes-Specific
-
rollingUpdate.maxUnavailableis set to 0 — no pod is terminated until a replacement is ready -
rollingUpdate.maxSurgeallows at least one extra pod to spin up during the rollout - Pod disruption budgets prevent the cluster from evicting too many pods simultaneously during node maintenance
- Shutdown hooks and termination grace time are based on measured draining behavior; hook execution consumes part of the grace period. See the Kubernetes pod lifecycle
Deploy: Feature Flags
- New or risky functionality is gated behind a feature flag, not shipped fully enabled
- The flag is tested in the disabled state before the deploy goes out
- The flag can be toggled without a new deploy
Post-Deploy: Verification
- Automated smoke tests run immediately after the deployment completes
- Key HTTP endpoints return expected status codes
- Error rate (HTTP 5xx) is at baseline for at least 5 minutes post-deploy
- P95 latency has not regressed
- Any critical business flows (checkout, authentication, primary API calls) work end-to-end
Post-Deploy: Rollback Readiness
- The previous artifact is available and a rehearsal meets the recovery-time target
- The rollback procedure has been documented and is accessible to any on-call engineer
- If a migration was run, the rollback plan accounts for the schema state
- The on-call engineer knows the rollback command or process before the deploy starts — not after something goes wrong
Failure Cases to Test
Readiness probes that lie. A health endpoint that returns 200 immediately on startup — before the database connection pool is established — will route traffic to an unready instance. That can send requests to an instance before it is able to serve them.
No draining on the load balancer. Removing an instance from rotation without draining existing connections terminates in-flight requests. Enable connection draining and set a drain timeout that matches your request duration.
Single-step column renames. Renaming a database column in one migration breaks the running application version that still references the old column name. This is a preventable outage.
Untested rollback paths. The rollback plan is only useful if it works. Test it in a staging environment with a representative schema state.