process.on("SIGTERM", () => {
console.log("shutting down");
server.close(async () => {
await db.end();
process.exit(0);
});
server.closeIdleConnections();
setTimeout(() => process.exit(1), 10_000).unref();
});
Listen for SIGTERM, stop taking new requests, finish the current ones, close your resources, then exit.
Why SIGTERM? Orchestrators like Docker and Kubernetes send SIGTERM to stop a container. After a grace period, they send SIGKILL. Your code cannot catch SIGKILL, so all cleanup must happen in the SIGTERM window.
The steps:
- Listen with
process.on('SIGTERM', ...). - Call
server.close(). It stops listening for new connections and waits for in-flight requests (requests already being handled). - Deal with keep-alive connections. They can keep the server open. Call
server.closeIdleConnections(), or after a deadline callserver.closeAllConnections(). - Close database pools, message consumers and other resources.
- Exit.
Add a timeout that forces process.exit(1) if cleanup hangs.
In Kubernetes, fail the readiness probe first. Then the load balancer stops sending traffic to the pod before you close the server.
SIGTERMcomes first andSIGKILLcomes after a grace period. Your code cannot handleSIGKILL.server.close()stops new connections and finishes in-flight requests.- Close keep-alive connections, because they can keep the server open.
- Close database pools, queues and other resources.
- Force an exit after a timeout if cleanup hangs.
Read more