Implement Graceful Shutdown

When the application receives a termination signal, it should stop accepting new connections and release resources cleanly.

The shutdown sequence should:

  1. Stop accepting new HTTP connections.
  2. Allow active requests to finish within a reasonable deadline.
  3. Disconnect from MongoDB.
  4. Exit the process.

This is particularly important in containerized environments and during automated deployments.

Production Shutdown Deadline

Add a shutdown timeout and account for keep-alive connections. Your application should complete cleanup within the hosting platform's termination grace period.

Graceful Shutdown
import http from 'node:http';
import app from './app.js';
import { connectDatabase, disconnectDatabase } from './config/database.js';

const server = http.createServer(app);

async function startServer() {
  await connectDatabase();

  server.listen(process.env.PORT || 3000);
}

async function shutdown(signal) {
  console.log(`${signal} received`);

  server.close(async (error) => {
    try {
      await disconnectDatabase();

      if (error) {
        console.error(error);
        process.exit(1);
      }

      process.exit(0);
    } catch (shutdownError) {
      console.error(shutdownError);
      process.exit(1);
    }
  });
}

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

startServer().catch((error) => {
  console.error(error);
  process.exit(1);
});

Creates an explicit HTTP server, closes it on termination, and disconnects from MongoDB before exiting.

Key Takeaways
  • Handle SIGTERM and SIGINT.

  • Stop accepting new connections during shutdown.

  • Close database connections before exiting.