Skip to content

Knowledgebase

Handling Node process restarts and graceful shutdown

development

A production application should stop accepting new work and finish or safely hand off current work when the process manager replaces it. Abrupt termination can leave requests and jobs in uncertain states.

What you need before you begin

Identify the supervisor’s stop signal and timeout. List the HTTP server, database pools, queue consumers and other resources the process owns.

01 Handle Node process restarts and graceful shutdown

  1. Handle the supported termination signal in the application. Mark the instance unready so the proxy or load balancer can stop sending new requests.

  2. Stop accepting new connections and allow in-flight requests an appropriate completion window. Set a finite deadline so shutdown cannot hang forever.

  3. Close database pools and other resources after their active work completes. Pause queue consumption and preserve the retry or visibility behavior for unfinished jobs.

  4. Coordinate the application deadline with the supervisor timeout. The supervisor must have enough time for the intended cleanup before forcing termination.

  5. Test a restart during a harmless slow request and a queued task. Observe whether clients receive a controlled result and jobs recover as designed.

02 Example: bound an Express shutdown without abandoning cleanup

Adapt this fragment to an existing HTTP server. Its readiness handler must return unhealthy once stopping becomes true, and closeApplicationResources must be your implemented cleanup for pools and consumers. The 15-second deadline is an example to coordinate with the supervisor.

Code or configuration example
let stopping = false;
process.once('SIGTERM', () => {
  stopping = true;
  const deadline = setTimeout(() => process.exit(1), 15000);
  deadline.unref();
  server.close(async (error) => {
    try {
      await closeApplicationResources();
      clearTimeout(deadline);
      process.exitCode = error ? 1 : 0;
    } catch {
      process.exitCode = 1;
    }
  });
});

Test with a harmless slow request and an isolated queue task. Stop new work before draining existing work, and account for upgraded connections such as WebSockets separately. The process manager should allow the intended cleanup window.

Expected result: The old instance leaves service, in-flight work finishes or recovers according to policy, and the replacement becomes ready. A stuck resource cannot keep the old process alive indefinitely.

Confirm the expected result

Confirm the replacement process starts, the old process exits and no abandoned connections accumulate. Check that external actions are not duplicated during job recovery.

Troubleshoot unexpected results

If shutdown stalls, identify the open connection or timer holding the process alive. A forced exit may be necessary as a final bound, but it should not be the only planned path.

A common question

Does a process manager automatically make application shutdown safe?

It manages process lifecycle. The application still needs to handle its active requests, resources and external work consistently within that lifecycle.

Was this answer helpful?

Need a little more help?

Our support team can help you find the next step.

Contact support