Spring Fresh Sale! - Up To 67% OFF BDIX Hosting + Free Domain
Node.js

How to Implement Graceful Shutdown in a Node.js Server

A graceful shutdown lets your Node.js server stop accepting new requests, finish the ones already in progress, close its database connections, and then exit cleanly — instead of being killed mid-request. It is essential for zero-downtime deploys and for not dropping users' work.

Why it matters

When you deploy or restart, the process receives a termination signal. Without handling it, Node dies instantly — cutting off in-flight requests, leaving database transactions half-done, and dropping connections. Graceful shutdown avoids all of that.

The signals to handle

Listen for SIGTERM (sent by process managers and orchestrators) and SIGINT (Ctrl+C):

process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);

The shutdown sequence

  1. Stop accepting new connections — call server.close(), which lets existing requests finish.
  2. Finish in-flight requestsserver.close()'s callback fires once they are done.
  3. Close resources — database pools, Redis clients, file handles.
  4. Exit — call process.exit(0).

function shutdown() { server.close(() => { db.end(); redis.quit(); process.exit(0); }); }

Add a safety timeout

If requests hang, do not wait forever — set a timeout that forces exit after, say, 10 seconds, so a stuck request cannot block the shutdown indefinitely.

Why it enables zero-downtime deploys

With graceful shutdown, PM2 reloads replace instances one at a time without dropping requests, and it pairs with proper error handling and monitoring for reliable operations.

Frequently asked questions

Which signal should I handle for deploys?

Primarily SIGTERM, which process managers and container platforms send to ask your app to stop. Also handle SIGINT for local Ctrl+C during development.

What if a request never finishes?

Add a forced-exit timeout so a hung request cannot block shutdown forever. After the grace period, exit anyway — better than hanging indefinitely.

Do I need this with PM2?

Yes — PM2's zero-downtime reloads rely on your app shutting down gracefully on SIGTERM. Without it, reloads can still drop in-flight requests.

Was this article helpful?