If your Node service does not handle SIGTERM, every deploy is a small outage. The fix is a graceful shutdown handler of about fifteen lines.
What happens without it
The pod gets the signal, the process dies immediately, and whatever requests were in flight just end. Users see a 502 and blame the feature you shipped.
The fix
Catch SIGTERM, stop accepting new connections, let in-flight requests finish, close the database pool, then exit. Give it a timeout so a stuck request cannot block the shutdown forever.
const server = app.listen(port);
process.on("SIGTERM", () => {
// Hard stop if something hangs
const timer = setTimeout(() => process.exit(1), 10_000);
timer.unref();
// Stop accepting new connections, wait for in-flight requests
server.close(async () => {
await db.end(); // close the database pool
process.exit(0);
});
});Keep the timeout shorter than your orchestrator's grace period, so your code decides how the process ends rather than a SIGKILL.
Nobody notices
Nobody notices when you get this right. That is sort of the point.
Takeaways
- Without a SIGTERM handler, every deploy cuts off in-flight requests.
- Stop accepting connections, drain requests, close pools, then exit.
- Add a timeout so a stuck request cannot block shutdown forever.
- It is a small amount of code for a quieter deploy.
Building something like this?
I'm Ahmed Mamdouh, a senior full-stack & AI engineer. I reply within one working day.
Scaling 100k WebSocket connections: the reconnect storm
At 100k+ concurrent sockets, the hard part is not the count but the reconnect storm; jittered backoff, load shedding and resumable sessions fix it.
npm v12 blocks install scripts by default
npm v12 no longer runs preinstall, install or postinstall scripts unless you approve them, closing a common supply chain attack path.
Node.js moves to one major release a year
From Node 27, Node.js ships one major a year and every release becomes LTS, ending the odd/even split most teams already ignored.