AceDevHub
Advanced Node.js Interview QuestionsAdvancedPractical

Node.js · Question 73

How do you implement graceful shutdown in Node.js?

Direct answer

On SIGTERM/SIGINT stop accepting connections with server.close(), finish in-flight requests, close DB/Redis pools and queue workers, set a force-exit timeout, then process.exit — Kubernetes and Docker send SIGTERM on deploy.

Abrupt process.kill mid-request causes 502s and half-open DB transactions — graceful shutdown drains work before exit during rolling deploys on AceDevHub API.

Why interviewers ask

  1. Signal handlers — process.on('SIGTERM', shutdown); same for SIGINT locally.
  2. Stop listening — server.close() — no new connections; existing finish.
  3. Close resources — await pool.end(), redis.quit(), BullMQ worker.close().
  4. Force timeout — setTimeout(() => process.exit(1), 30_000).unref() as last resort.
graceful-shutdown.mjs
let shuttingDown = false;

async function shutdown(signal) {
  if (shuttingDown) return;
  shuttingDown = true;
  console.log(`${signal} received — draining`);

  await new Promise((resolve) => server.close(resolve));
  await pgPool.end();
  await redis.quit();
  process.exit(0);
}

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