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.