Graceful Shutdown in Node.js: Stop Dropping Requests
Your server gets a SIGTERM. It dies immediately. In-flight requests get 502s. Here is how to shut down properly.
The Basic Pattern
import http from "http";
let isShuttingDown = false;
const server = http.createServer(app);
async function gracefulShutdown(signal: string) {
isShuttingDown = true;
server.close();
const timeout = setTimeout(() => process.exit(1), 30000);
await Promise.all([closeDatabase(), closeRedis(), flushLogs()]);
clearTimeout(timeout);
process.exit(0);
}
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
process.on("SIGINT", () => gracefulShutdown("SIGINT"));
Health Check During Shutdown
app.get("/health", (req, res) => {
if (isShuttingDown) return res.status(503).json({ status: "shutting_down" });
res.json({ status: "healthy" });
});
Returning 503 tells the load balancer to stop sending new traffic.
What to Clean Up
- Stop accepting new requests
- Finish in-flight requests (with timeout)
- Close database connection pools
- Disconnect from Redis and message brokers
- Flush log buffers
- Deregister from service discovery
Part of my Production Backend Patterns series. Follow for more practical backend engineering.
You Might Also Like
- BullMQ Job Queues in Node.js: Background Processing Done Right (2026 Guide)
- Scaling WebSocket Connections: From Single Server to Distributed Architecture (2026)
- Express Middleware Patterns: Composition, Error Handling, and Auth (2026 Guide)
Follow me for more production-ready backend content!
If this helped you, buy me a coffee on Ko-fi!
Top comments (0)