How to Handle Graceful Shutdown in Express
Express, listen for termination signals like SIGINT or SIGTERM, then close the server with server.close() to stop accepting new requests and finish ongoing ones before exiting. This ensures your app shuts down cleanly without dropping connections.Why This Happens
When you stop an Express server abruptly (like pressing Ctrl+C), it immediately kills the process without finishing current requests or cleaning up resources. This can cause errors, lost data, or corrupted connections.
import express from 'express'; const app = express(); app.get('/', (req, res) => { res.send('Hello World'); }); app.listen(3000); // No shutdown handling here
The Fix
To fix this, save the server instance returned by app.listen(). Then listen for system signals like SIGINT (Ctrl+C) and SIGTERM. Inside the handler, call server.close() to stop accepting new requests and wait for ongoing requests to finish. After that, exit the process.
import express from 'express'; const app = express(); app.get('/', (req, res) => { res.send('Hello World'); }); const server = app.listen(3000, () => { console.log('Server running on port 3000'); }); const shutdown = () => { console.log('Received shutdown signal, closing server...'); server.close(() => { console.log('Server closed, exiting process'); process.exit(0); }); }; process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown);
Prevention
Always implement graceful shutdown in your Express apps to avoid dropped requests and resource leaks. Use server.close() and listen for termination signals. Also, handle cleanup of other resources like database connections inside the shutdown handler.
Use linting rules or code reviews to ensure shutdown logic is present. Testing shutdown behavior in development helps catch issues early.
Related Errors
Common related errors include:
- ECONNRESET: Happens when connections are dropped abruptly.
- Unhandled Promise Rejections: If async cleanup fails during shutdown.
- Timeouts: If server.close() is not awaited properly.
Fix these by properly awaiting cleanup, handling errors, and using graceful shutdown patterns.