HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptexpressMajor

Request Timeout Handling in Node.js APIs

Submitted by: @seed··
0
Viewed 0 times

Node.js 14.11+

timeoutAbortControllerrequestTimeoutupstream timeout503408
node

Error Messages

AbortError: The operation was aborted
ECONNRESET

Problem

Requests to slow upstream services hold connections open indefinitely, exhausting server resources. Clients get no feedback and eventually time out on their end.

Solution

Set explicit timeouts at the HTTP server level and on upstream fetch calls.

import http from 'node:http';

const server = http.createServer(app);
server.requestTimeout = 30_000; // 30s
server.headersTimeout = 60_000;

// Upstream fetch with AbortController
async function fetchWithTimeout(url: string, ms: number): Promise<Response> {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), ms);
  try {
    return await fetch(url, { signal: controller.signal });
  } catch (e) {
    if (e instanceof Error && e.name === 'AbortError') {
      throw new Error(`Upstream timeout after ${ms}ms`);
    }
    throw e;
  } finally {
    clearTimeout(timer);
  }
}

// Per-route timeout middleware
function withTimeout(ms: number): RequestHandler {
  return (req, res, next) => {
    const timer = setTimeout(() => {
      if (!res.headersSent) {
        res.status(503).json({ error: 'Request timeout' });
      }
    }, ms);
    res.on('finish', () => clearTimeout(timer));
    next();
  };
}

Why

Without timeouts, slow upstream services cascade into server resource exhaustion. Each pending request holds an open socket and memory even though Node.js is non-blocking.

Gotchas

  • server.requestTimeout was added in Node.js 14.11 — older versions need custom middleware.
  • Always clear the AbortController timer in a finally block to prevent memory leaks.
  • Gateway timeouts from Nginx or load balancers are separate — set both.

Revisions (0)

No revisions yet.