Migrate from Heroku and get up to $10k in credits

Get started
Platform

How Render handles zero-downtime deploys

How zero-downtime deploys work

When you deploy a Render web service, Render keeps your application available while replacing the old version with the new one. In practice, avoiding dropped requests depends on both Render's deployment flow and your application's startup, health check, and shutdown behavior.

Render builds and starts a new instance of your application while the current instance keeps serving traffic. Once the new instance is ready, Render routes new requests to it and begins shutting down the older instance. Your application still needs to cooperate by reporting readiness accurately and by draining in-flight work cleanly when it receives termination signals.

Zero-downtime deploys apply to web services, private services, background workers, and cron jobs. Static sites also update with zero downtime but are backed by a CDN and don't involve service instances. Services with an attached persistent disk are the exception: adding a persistent disk disables zero-downtime deploys.

The deploy sequence

Each deploy follows these steps in order:

  1. Build the new artifact.
  2. Run pre-deploy commands (if configured) in a separate, temporary environment.
  3. Boot the new instance alongside the active one.
  4. Gate on health checks (or port binding) before routing traffic.
  5. Switch traffic to the new instance.
  6. After 60 seconds, send SIGTERM to the old instance.
  7. If the old instance doesn't exit within the shutdown delay, send SIGKILL.

Render does not send traffic to the new instance until it is considered ready. If you configure a health check path, Render uses that endpoint to verify readiness. Otherwise, Render falls back to detecting that the service is listening on its assigned port, which is why an explicit health check is usually the safer choice.

For long-lived connections like WebSockets or Server-Sent Events (SSE), zero-downtime routing applies only to the initial HTTP handshake. When the old instance eventually terminates, active WebSocket connections break. Your clients should implement reconnection logic to re-establish these connections with the new instance.

Configure health checks for readiness

Render supports HTTP health checks to verify that a new instance is ready to receive traffic. You can configure a health check path in the Render Dashboard or via healthCheckPath in your render.yaml file. If you do not configure one, Render falls back to checking whether the service has bound to its assigned port.

You must understand the difference between application liveness and application readiness. Liveness means your server process runs and binds to a port. Readiness means your server has established its required dependencies, such as database connections, cache clients, or configuration needed to serve real requests. A health check path gives Render a stronger readiness signal than port binding alone.

This minimal example demonstrates how an Express application might verify database readiness before passing a health check, returning standard HTTP status codes based on internal state variables:

For production, add robust timeout limits, comprehensive dependency checks, and proper logging. Please note that this code requires adaptation for your specific context; it intentionally omits authentication, detailed error parsing, comprehensive logging, and production routing structures.

Handle shutdown gracefully

Once the health check passes and Render switches traffic to the new instance, the old instance keeps running for 60 seconds before Render sends it a SIGTERM signal.

After receiving SIGTERM, your application has a configurable shutdown delay (default 30 seconds) to clean up. If the process is still running after the shutdown delay, Render sends SIGKILL to terminate it immediately. You can extend the shutdown delay up to 300 seconds via maxShutdownDelaySeconds in your render.yaml or through the Render API.

To prevent dropped connections, your application should catch SIGTERM and follow this sequence:

  1. Immediately stop accepting new connections (for example, calling server.close() in Node.js).
  2. Allow currently executing HTTP requests to finish writing their responses.
  3. Explicitly sever keep-alive sockets.
  4. Drain database connection pools before invoking process.exit().

If you implement a forced shutdown timer slightly shorter than your configured shutdown delay, your application can log incomplete drains before Render sends SIGKILL.

This demonstrates the core pattern for catching a SIGTERM and allowing in-flight requests to finish:

For production, add error handling during the shutdown sequence and ensure you cleanly pause background jobs. Please note that this code requires adaptation for your specific context; it intentionally omits advanced connection draining logic, Redis/Cache teardown, and cluster mode handling.

Common mistakes to avoid

A frequent mistake is hardcoding your health check endpoint to always return 200 OK immediately on boot. If your application needs a few seconds to establish a database connection pool, returning 200 prematurely tells Render to route traffic to an instance that isn't ready. Those requests fail, causing perceived downtime.

Ignoring SIGTERM also causes dropped connections. Without a signal handler, your application keeps running until Render’s shutdown delay expires and Render sends SIGKILL, which terminates all in-flight requests and open sockets immediately.

Finally, don't confuse pre-deploy commands with your application's startup sequence. Pre-deploy commands run in a separate temporary environment, which makes them useful for tasks like database migrations. They cannot keep a web server running or preserve in-memory state for the instance that eventually serves traffic.

Next steps

To learn more about deploying on Render, explore these resources:

  • Zero-downtime deploys: the full deploy sequence, including how Render handles overlapping deploys and rollbacks.
  • Health checks: configure a health check endpoint to verify readiness before Render routes traffic.
  • Pre-deploy commands: run database migrations or other setup tasks before each deploy.
  • Blueprint specification: define healthCheckPath and maxShutdownDelaySeconds in your render.yaml.

Frequently asked questions