typescriptintermediate
Node.js Graceful Shutdown Handler
Implement graceful shutdown to properly close connections and finish requests before exit.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { createServer, IncomingMessage, ServerResponse } from 'node:http';
const connections = new Set<import('node:net').Socket>();
let isShuttingDown = false;
const server = createServer((req: IncomingMessage, res: ServerResponse) => {
if (isShuttingDown) {
res.writeHead(503, { 'Connection': 'close' });
res.end('Server is shutting down');
return;
}
// Normal request handling
res.writeHead(200);
res.end('OK');
});
// Track active connections
server.on('connection', (socket) => {
connections.add(socket);
socket.on('close', () => connections.delete(socket));
});
async function shutdown(signal: string) {
if (isShuttingDown) return;
isShuttingDown = true;
console.log(`\n${signal} received. Starting graceful shutdown...`);
// Stop accepting new connections
server.close(() => {
console.log('HTTP server closed');
});
// Close idle keep-alive connections
for (const socket of connections) {
socket.end();
}
// Cleanup resources
try {
// await database.disconnect();
// await cache.quit();
// await messageQueue.close();
console.log('Resources cleaned up');
} catch (err) {
console.error('Cleanup error:', err);
}
// Force exit after timeout
const forceTimeout = setTimeout(() => {
console.error('Forced shutdown after timeout');
process.exit(1);
}, 10_000);
forceTimeout.unref();
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
process.on('uncaughtException', (err) => {
console.error('Uncaught exception:', err);
shutdown('uncaughtException').then(() => process.exit(1));
});
server.listen(3000, () => console.log('Server running on :3000'));Use Cases
- Production Node.js server reliability
- Zero-downtime deployment support
- Proper resource cleanup on shutdown
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptadvanced
Graceful Server Shutdown
Handle SIGTERM and SIGINT signals to drain connections, close database pools, and exit cleanly.
Best for: Production server deployment
#server#shutdown
typescriptadvanced
Graceful HTTP Server Shutdown
Production-ready server shutdown that drains active connections and closes resources cleanly.
Best for: Container deployments
#server#shutdown
javascriptintermediate
PM2 Process Manager Configuration
PM2 ecosystem file for managing Node.js processes with clustering, log rotation, and auto-restart.
Best for: Running Node.js in production with clustering
#pm2#process-manager
typescriptadvanced
Node.js Worker Threads for Parallel Processing
Use Worker Threads to run CPU-intensive tasks in parallel without blocking the event loop.
Best for: CPU-intensive data processing without blocking
#nodejs#worker-threads