How to handle process signals in Node.js
Process signals allow Node.js applications to respond to system events like termination requests, enabling graceful shutdowns and proper resource cleanup. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented signal handling in Node.js production servers throughout my 11 years of backend development. The most reliable approach is listening for SIGTERM and SIGINT signals to perform cleanup operations before process termination. This method ensures database connections close, pending requests complete, and temporary files are removed before shutdown.
Listen for SIGTERM and SIGINT signals to handle graceful shutdown and resource cleanup.
const express = require('express')
const app = express()
const server = app.listen(3000, () => {
console.log('Server running on port 3000')
})
const gracefulShutdown = (signal) => {
console.log(`Received ${signal}, starting graceful shutdown`)
server.close(() => {
console.log('HTTP server closed')
// Close database connections
// database.close()
// Clean up temporary files
// cleanup()
console.log('Cleanup completed, exiting')
process.exit(0)
})
// Force shutdown after timeout
setTimeout(() => {
console.error('Forced shutdown after timeout')
process.exit(1)
}, 10000)
}
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'))
process.on('SIGINT', () => gracefulShutdown('SIGINT'))
console.log('Press Ctrl+C to trigger graceful shutdown')
Here process.on() registers listeners for SIGTERM (sent by container orchestrators like Kubernetes) and SIGINT (sent by Ctrl+C). The gracefulShutdown function calls server.close() to stop accepting new connections while allowing existing requests to complete. The callback executes after all connections close, performing database cleanup and other shutdown tasks. The setTimeout provides a forced exit after 10 seconds, preventing hung processes if cleanup operations fail to complete.
Best Practice Note:
This is the shutdown handling we implement in CoreUI Node.js services for production deployments with zero-downtime updates. Handle multiple signals (SIGTERM, SIGINT, SIGHUP) for different scenarios, set appropriate shutdown timeouts based on request duration patterns, and log shutdown events for debugging failed graceful shutdowns in production environments.



