{"id":17085,"library":"connect-timeout","title":"Connect/Express Request Timeout Middleware","description":"connect-timeout is a middleware for Connect and Express applications designed to terminate long-running HTTP requests after a specified duration. The current stable version is 1.9.1. It provides functionality to emit a 'timeout' event on the request object and, optionally, forward a 503 Service Unavailable error to the next middleware. While it flags timed-out requests, it's crucial to understand that it does not inherently stop the underlying server-side processing of the request; developers must explicitly check `req.timedout` to halt further execution and manage resource consumption. Its primary differentiation is its tight integration with the Connect/Express middleware pattern, allowing for flexible placement in the middleware chain, though it warns against top-level usage without precautions. Release cadence appears moderate, with dependency updates and minor fixes.","status":"active","version":"1.9.1","language":"javascript","source_language":"en","source_url":"https://github.com/expressjs/timeout","tags":["javascript"],"install":[{"cmd":"npm install connect-timeout","lang":"bash","label":"npm"},{"cmd":"yarn add connect-timeout","lang":"bash","label":"yarn"},{"cmd":"pnpm add connect-timeout","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used for parsing time strings (e.g., '5s', '2h') into milliseconds.","package":"ms","optional":false},{"reason":"Used for creating HTTP-specific error objects, specifically for the 503 timeout error.","package":"http-errors","optional":false},{"reason":"Utility to execute a callback when response headers are about to be sent. Ensures proper cleanup and handling.","package":"on-headers","optional":false}],"imports":[{"note":"The connect-timeout library exports its main middleware function as a default export, even when used with ES Modules through transpilation or bundlers. CommonJS `require` is `const timeout = require('connect-timeout')`.","wrong":"import { timeout } from 'connect-timeout'","symbol":"timeout","correct":"import timeout from 'connect-timeout'"},{"note":"This package is primarily designed for CommonJS environments common in older Node.js/Express applications. While it can be used with ESM, this `require` pattern is the most common and direct usage.","symbol":"timeout factory function","correct":"const timeout = require('connect-timeout')"},{"note":"The function call `timeout('5s')` returns the actual middleware function to be used with `app.use()` or `router.use()`.","symbol":"Middleware usage","correct":"app.use(timeout('5s'))"}],"quickstart":{"code":"import express from 'express';\nimport timeout from 'connect-timeout';\n\nconst app = express();\n\n// A function to simulate a long-running async operation\nfunction simulateAsyncTask(durationMs) {\n  return new Promise(resolve => {\n    setTimeout(() => {\n      console.log(`Async task finished after ${durationMs}ms.`);\n      resolve();\n    }, durationMs);\n  });\n}\n\n// Helper middleware to check if request has timed out and halt further processing\nfunction haltOnTimedout(req, res, next) {\n  if (!req.timedout) {\n    next();\n  } else {\n    console.warn(`Request to ${req.originalUrl} timed out.`);\n    // Optionally send a custom response here, or let the error handler catch it\n    if (!res.headersSent) {\n       res.status(503).send('Service Unavailable: Request timed out.');\n    }\n  }\n}\n\n// Route with a 3-second timeout\napp.get('/slow-task', timeout('3s'), haltOnTimedout, async (req, res, next) => {\n  try {\n    const randomDelay = Math.random() * 5000 + 1000; // 1 to 6 seconds\n    console.log(`Starting slow task for ${randomDelay}ms.`);\n    await simulateAsyncTask(randomDelay);\n    \n    // Check if the request has already timed out before sending a response\n    if (req.timedout) {\n      console.log('Request timed out before sending success response.');\n      return; // Do not send response if already timed out\n    }\n\n    res.status(200).send('Task completed successfully!');\n  } catch (error) {\n    next(error);\n  }\n});\n\n// Error handling middleware for timeout errors\napp.use((err, req, res, next) => {\n  if (err.timeout) {\n    console.error('Request timeout error caught by error handler:', err.message);\n    // The `haltOnTimedout` middleware above already handles the response,\n    // but this ensures any other timeout scenarios are caught.\n    if (!res.headersSent) {\n      res.status(503).send('Service Unavailable: Caught by error handler.');\n    }\n  } else {\n    console.error('General error:', err.message);\n    if (!res.headersSent) {\n      res.status(500).send('Internal Server Error.');\n    }\n  }\n});\n\nconst PORT = 3000;\napp.listen(PORT, () => {\n  console.log(`Server listening on port ${PORT}`);\n  console.log('Try accessing http://localhost:3000/slow-task');\n});\n","lang":"typescript","description":"This quickstart demonstrates how to apply `connect-timeout` to an Express route, implement a `haltOnTimedout` helper middleware to prevent further processing, and catch timeout errors. It simulates a slow asynchronous task to trigger the timeout and shows how to check `req.timedout` before responding."},"warnings":[{"fix":"After any middleware that might take time, insert a check like `function haltOnTimedout (req, res, next) { if (!req.timedout) next() }`. Also, ensure your route handlers check `req.timedout` before attempting to send a response or perform further operations.","message":"Using `connect-timeout` as a top-level middleware (`app.use(timeout('5s'))`) without `haltOnTimedout` or similar checks can lead to resource leaks. The middleware will emit a 'timeout' event and potentially send a 503 response, but the underlying request processing (e.g., database queries, heavy computations) will continue in Node.js, consuming CPU and memory resources.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Listen for the 'timeout' event on `req`: `req.on('timeout', () => { /* custom logic */ });` or ensure your error-handling middleware correctly processes errors with `err.timeout === true` and `err.status === 503`.","message":"The `timeout` event is emitted on the `req` object, not `res`. While `respond: true` (the default) will pass a 503 error to `next()`, explicit handling of the 'timeout' event on `req` might be necessary for specific logic or custom responses outside the standard error handling chain.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `connect-timeout@1.7.0` or higher to resolve potential memory leak issues related to timer cleanup on keep-alive connections.","message":"Older versions of `connect-timeout` (prior to v1.7.0) used to override socket destroy methods, which could lead to memory leaks on keep-alive connections. This was fixed by switching to `on-finished`.","severity":"deprecated","affected_versions":"<1.7.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that all middleware and route handlers check `req.timedout` before attempting to send a response. Implement a `haltOnTimedout` middleware immediately after any potentially slow middleware.","cause":"The timeout middleware sent a 503 response, but the original request handler or a subsequent middleware also tried to send a response.","error":"Error: Can't set headers after they are sent to the client."},{"fix":"Provide a valid time string (e.g., `'5s'`, `'1000ms'`) or a number (in milliseconds) as the first argument to `timeout()`: `app.use(timeout('5s'))`.","cause":"The `timeout` function was called without an argument or with an invalid time string, leading it to return `undefined` instead of a middleware function.","error":"TypeError: app.use() requires a middleware function but got a undefined"},{"fix":"Implement an error-handling middleware (`app.use((err, req, res, next) => { ... })`) that specifically checks for `err.timeout === true` and `err.status === 503` to provide a custom response or log the event.","cause":"This is the error object passed to `next()` when a request times out and the `respond` option is `true` (which is the default). It signifies that the `connect-timeout` middleware has detected a timeout.","error":"ConnectTimeoutError: Service Unavailable"}],"ecosystem":"npm","meta_description":null}