intermediate

Graceful shutdown

Handle signals, stop accepting work, drain in-flight requests, close resources, and respect orchestrator timeouts.

Graceful shutdown stops accepting new work, drains in-flight requests, closes connections and background resources, then exits — required for zero-downtime deploys and data integrity.

					let shuttingDown = false;
const server = app.listen(PORT);

async function shutdown(signal) {
  if (shuttingDown) return;
  shuttingDown = true;
  logger.info({ signal }, 'shutdown started');
  server.close(() => logger.info('HTTP closed'));
  await Promise.race([
    drainInFlight(),
    sleep(orchestratorTimeoutMs),
  ]);
  await db.close();
  process.exit(0);
}

process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
				

Kubernetes sends SIGTERM then kills after `terminationGracePeriodSeconds`. Close DB pools, message consumers, and timers. Keep readiness probe failing while draining so load balancers stop sending traffic.

On interviews: SIGTERM vs SIGINT; interaction with `server.close`; hard timeout fallback.

Common pitfalls: infinite drain waiting; not stopping cron/queue consumers; exiting before DB transactions commit.

The trade-off is balancing simplicity, performance, safety, and operability — name which axis you optimized and what cost you accepted.

Checklist:

  • Stop accept + fail health checks early.
  • Track in-flight request count.
  • Bounded shutdown timeout then force exit.
  • Integration test shutdown path.