Course contentsShow
← Node.js
Lesson 1404 of 1,98013. Error Handling and Resilient SystemsFree lesson

Handling SIGTERM and SIGINT Signals

You will write signal listeners that initiate a clean teardown sequence for long-running server processes.

In this lesson, you will learn how to implement graceful shutdown sequences in Node.js to ensure your server completes pending tasks before exiting.

When you run a long-lived Node.js process—like an HTTP server or a cache-syncing worker—the operating system manages its lifecycle. When you press Ctrl+C in your terminal, the process receives a SIGINT (Signal Interrupt). When a cloud orchestrator like Kubernetes wants to stop your container, it sends a SIGTERM (Signal Terminate). By default, Node.js kills the process immediately, which can result in broken database connections, corrupted cache files, or interrupted client requests.

To handle these gracefully, we listen for these signals and initiate a teardown sequence.

Implementing the Teardown Sequence

The goal is to stop accepting new work, finish in-flight operations, and then exit. Here is how you structure that logic:

const server = http.createServer(/* ... */);

const shutdown = (signal) => {
  console.log(`Received ${signal}. Starting graceful shutdown...`);

  // 1. Stop accepting new connections
  server.close(() => {
    console.log('HTTP server closed.');
    // 2. Perform cleanup (e.g., flush buffers, close DB pools)
    process.exit(0); 
  });
};

// Listen for signals
process.on('SIGINT', () => shutdown('SIGINT'));
process.on('SIGTERM', () => shutdown('SIGTERM'));

When server.close() is called, Node.js stops the server from accepting new connections but keeps existing ones open until they finish their work. Once the last request completes, the callback fires, allowing you to safely close database connections or flush remaining logs before exiting the process with process.exit(0).

If you have complex logic, such as a multi-tiered cache, your shutdown function acts as the orchestrator. You might first signal your cache manager to persist pending data, then close the server, and finally sever your network sockets. This prevents the "silent failures" we discussed earlier by ensuring that stateful data has a chance to reach its destination before the process vanishes.

Key Takeaway: Always intercept SIGINT and SIGTERM to close your server gracefully, ensuring that active requests are finished and resources are cleaned up before the process terminates.