{"id":11055,"library":"http-graceful-shutdown","title":"HTTP Graceful Shutdown","description":"http-graceful-shutdown is a Node.js utility library designed to ensure HTTP and HTTPS servers (including those built with frameworks like Express, Koa, and Fastify, or native Node.js http/http2) shut down cleanly and without disrupting active client connections. It manages open sockets, stops accepting new connections, and allows for the registration of custom cleanup functions (e.g., closing database connections) to execute before the server fully terminates. The library tracks all connections, gracefully communicates shutdown intent to clients, and can optionally destroy remaining sockets forcefully after a timeout. Version 3.1.16 is the current stable release, with version 3.0 being a significant update that improved internal handling while maintaining backward compatibility with 2.x. It has seen over 35 million downloads, indicating its widespread adoption for robust application termination. The release cadence appears stable, with major versions being well-tested.","status":"active","version":"3.1.16","language":"javascript","source_language":"en","source_url":"https://github.com/sebhildebrandt/http-graceful-shutdown","tags":["javascript","http","https","koa","express","fastify","shutdown","graceful","force","typescript"],"install":[{"cmd":"npm install http-graceful-shutdown","lang":"bash","label":"npm"},{"cmd":"yarn add http-graceful-shutdown","lang":"bash","label":"yarn"},{"cmd":"pnpm add http-graceful-shutdown","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the common method for importing the `gracefulShutdown` function in CommonJS environments, as used in the official quickstart. The module exposes a default export.","wrong":"import { gracefulShutdown } from 'http-graceful-shutdown';","symbol":"gracefulShutdown (CommonJS)","correct":"const gracefulShutdown = require('http-graceful-shutdown');"},{"note":"For ESM environments, `http-graceful-shutdown` is consumed as a default import. Ensure your `package.json` specifies `\"type\": \"module\"` or use a `.mjs` file extension for proper resolution.","wrong":"import * as gracefulShutdown from 'http-graceful-shutdown';","symbol":"gracefulShutdown (ESM)","correct":"import gracefulShutdown from 'http-graceful-shutdown';"},{"note":"If you are using TypeScript and need explicit type annotations for the configuration object passed to `gracefulShutdown`, you can import the `Options` type.","symbol":"Options (TypeScript)","correct":"import type { Options } from 'http-graceful-shutdown';"}],"quickstart":{"code":"const express = require('express');\nconst http = require('http');\nconst gracefulShutdown = require('http-graceful-shutdown');\n\nconst app = express();\napp.get('/', (req, res) => {\n  console.log('Request received at /');\n  // Simulate a long-running request that might be in progress during shutdown\n  setTimeout(() => {\n    res.send('Hello from server! Shutting down soon...');\n  }, 2000);\n});\n\nconst PORT = process.env.PORT || 3000;\nconst server = http.createServer(app);\n\nserver.listen(PORT, () => {\n  console.log(`Server running on port ${PORT}`);\n  console.log('Press Ctrl+C to initiate graceful shutdown.');\n});\n\n// This enables the graceful shutdown mechanism\ngracefulShutdown(server, {\n  forceExit: true, // Default is true, causes process.exit after timeout\n  timeout: 10000, // how long to wait before force exiting (in ms)\n  // Register custom cleanup functions to run before the server fully terminates\n  onShutdown: async (signal) => {\n    console.log(`Server received ${signal}. Running cleanup...`);\n    // Example: Close database connections or other resources\n    await new Promise(resolve => setTimeout(resolve, 3000)); // Simulate async cleanup\n    console.log('Cleanup complete!');\n  },\n  finally: () => {\n    console.log('Server shutdown sequence finished. Goodbye!');\n  }\n});","lang":"javascript","description":"This quickstart demonstrates how to integrate `http-graceful-shutdown` with an Express application, showing server initialization, handling a simulated long-running request, and registering custom cleanup functions during a graceful shutdown triggered by signals like `SIGINT` or `SIGTERM`."},"warnings":[{"fix":"Thoroughly test existing shutdown logic and custom cleanup functions after upgrading to ensure expected behavior. Review the examples for version 3.x to understand any changes in best practices.","message":"Version 3.0 introduced significant internal changes for 'much better handling'. While stated as 'fully backwards compatible to version 2.x', users upgrading from 1.x or early 2.x might encounter subtle behavioral differences, especially concerning how connections are tracked or `preShutdown` hooks are invoked due to the underlying improvements.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"If conflicts arise, configure `http-graceful-shutdown` to disable automatic signal handling (`disableSignalHandlers: true`) and manually trigger shutdown using `gracefulShutdown.shutdown()` within your own signal handler. Alternatively, ensure `http-graceful-shutdown` is initialized last to give it priority.","message":"The library registers signal handlers (e.g., SIGINT, SIGTERM) by default. If your application or other libraries also register handlers for these signals, they might conflict, leading to unexpected shutdown behavior or preventing `http-graceful-shutdown` from taking control.","severity":"gotcha","affected_versions":"*"},{"fix":"To prevent `process.exit()`, set `forceExit: false` in the options passed to `gracefulShutdown(server, { forceExit: false })`. Be aware that without `forceExit`, your application might hang if any lingering event loop tasks or open handles prevent it from naturally exiting.","message":"By default, `http-graceful-shutdown` will call `process.exit(0)` after the timeout to ensure the process terminates. If your application relies on the event loop draining naturally after shutdown (e.g., for testing frameworks or other background processes), this forceful exit can abruptly terminate those operations.","severity":"gotcha","affected_versions":"*"},{"fix":"Carefully calculate the `timeout` value based on your longest expected request processing time plus any synchronous or asynchronous cleanup operations. Test various shutdown scenarios under load to find an optimal balance.","message":"An improperly configured `timeout` can lead to either abrupt termination of active requests (if too short) or prolonged application unavailability during restarts (if too long). This timeout includes the duration of `onShutdown` and `preShutdown` hooks.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure all long-running processes and connections (like database clients, Redis, message queues) are explicitly closed within the `onShutdown` or `preShutdown` hooks. Alternatively, set `forceExit: true` (which is the default) to ensure termination after the configured timeout, or manually call `process.exit()` in your `finally` hook.","cause":"The `forceExit` option is set to `false`, and some asynchronous operations (e.g., open database connections, message queue consumers, scheduled timers) are preventing the Node.js event loop from clearing naturally after the HTTP server stops.","error":"Server did not exit after shutdown, hanging process."},{"fix":"Use the correct import statement for a default export: `import gracefulShutdown from 'http-graceful-shutdown';` for ESM, or `const gracefulShutdown = require('http-graceful-shutdown');` for CommonJS.","cause":"Incorrect import style, likely attempting a named import (`import { gracefulShutdown } from 'http-graceful-shutdown';`) when the module provides a default export.","error":"TypeError: gracefulShutdown is not a function"},{"fix":"Wrap the asynchronous operations within your `onShutdown` and `preShutdown` functions in `try...catch` blocks or chain `.catch()` to handle potential rejections gracefully. While the library itself handles errors within these hooks to prevent process crashes, logging and specific error handling are your responsibility.","cause":"An asynchronous cleanup function registered with `onShutdown` or `preShutdown` rejected a promise, and this rejection was not caught within the hook.","error":"UnhandledPromiseRejectionWarning: A promise was rejected with a reason that was not handled during shutdown."}],"ecosystem":"npm"}