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

Timeout Strategies for Hanging Processes

You will implement a 'force-exit' timer to prevent zombies if graceful shutdown hangs indefinitely.

In this lesson, you will learn how to implement a 'force-exit' timer to ensure your Node.js application terminates reliably even if your graceful shutdown sequence hangs indefinitely.

The Problem: The "Ghost" Process

When your application receives a SIGTERM or SIGINT signal, you naturally begin a cleanup phase—closing database pools, flushing logs, or finishing active HTTP requests. However, if a resource cleanup operation hangs (e.g., a database connection that refuses to close due to a network partition), your process becomes a "zombie." It sits in memory, blocking ports and failing to restart, effectively rendering your deployment pipeline useless.

The Strategy: The "Hard" Timeout

To prevent this, we implement a "shutdown watchdog." Instead of waiting forever for our cleanup functions to resolve, we set a setTimeout at the very beginning of the shutdown process. This timer acts as a deadline; if the cleanup doesn't finish before the clock runs out, we force the process to exit immediately using process.exit(1).

Implementing the Watchdog

Here is how you can wrap your cleanup logic to guarantee termination:

const shutdown = async () => {
  // Set a 5-second hard limit for cleanup
  const forceExit = setTimeout(() => {
    console.error('Shutdown hung. Forcing exit...');
    process.exit(1);
  }, 5000);

  try {
    // Perform your resource cleanup orchestration here
    await closeDatabaseConnections();
    await closeWebSockets();
    
    // Clear the timer if cleanup succeeds
    clearTimeout(forceExit);
    process.exit(0);
  } catch (err) {
    console.error('Error during shutdown:', err);
    process.exit(1);
  }
};

process.on('SIGTERM', shutdown);

By utilizing clearTimeout(forceExit), we ensure that if our graceful shutdown completes successfully and promptly, the process exits cleanly. If it hangs, the setTimeout callback executes, tearing down the process and preventing the "zombie" state. This approach honors the Philosophy of Failing Fast by acknowledging that an unresponsive cleanup routine is better terminated than left to linger indefinitely.

Key Takeaway: Always pair your graceful shutdown orchestration with a final, non-negotiable timeout to guarantee that your process exits, even when your cleanup logic fails to resolve.