Graceful Shutdown in Node.js: Stop Losing Requests During Deploys
Your deploy kills in-flight requests. Users get 502s. Database transactions hang open.
The Problem
SIGTERM arrives. process.exit() runs. Active connections drop. Users see errors.
The Fix
import http from "http";
import { Pool } from "pg";
const pool = new Pool();
const app = express();
const server = http.createServer(app);
let isShuttingDown = false;
app.use((req, res, next) => {
if (isShuttingDown) return res.status(503).json({ error: "Shutting down" });
next();
});
async function shutdown(signal: string) {
console.log(`Received ${signal}. Starting graceful shutdown...`);
isShuttingDown = true;
server.close(() => console.log("HTTP server closed"));
await pool.end();
process.exit(0);
}
process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));
setTimeout(() => { console.error("Forced shutdown"); process.exit(1); }, 30000);
The Shutdown Order
- Stop accepting new connections (server.close)
- Reject new requests with 503 (isShuttingDown middleware)
- Wait for in-flight requests to complete
- Close database connections (pool.end)
- Close Redis, message queues, other external connections
- Force kill after timeout (safety net)
Health Check Integration
Your load balancer needs to know you are shutting down:
app.get("/healthz", (req, res) => {
if (isShuttingDown) return res.status(503).send("shutting down");
res.status(200).send("ok");
});
Docker + Kubernetes
Kubernetes sends SIGTERM and waits terminationGracePeriodSeconds (default 30s) before SIGKILL. Your app must finish within that window.
In Docker, use exec form CMD so SIGTERM reaches Node directly:
CMD ["node", "dist/server.js"]
Not CMD node dist/server.js which runs via shell and swallows signals.
Common Mistakes
- Calling process.exit() immediately - Kills in-flight requests
- No timeout - A stuck request hangs shutdown forever
- Shell form in Dockerfile - Signals never reach Node
- Forgetting database cleanup - Connections leak and exhaust pool
Part of my Production Backend Patterns series. Follow for more practical backend engineering.
Top comments (0)