Safeguard
Security Guides•

What do Node.js headersTimeout and requestTimeout do against slow clients?

Node's HTTP server sets headersTimeout, requestTimeout and keepAliveTimeout by default. See the documented values and when to tighten them for slow clients

Safeguard Security Team
3 min read

Node's HTTP server has built in timeouts against slow senders. headersTimeout limits how long the server waits for complete headers, requestTimeout limits how long it waits for the entire request, and keepAliveTimeout closes idle connections. Check each value, because the defaults are not all strict, and server.timeout is off.

Definitions and documented defaults

SettingDocumented defaultWhat it limits
headersTimeoutThe smaller of requestTimeout or 60000 msTime to receive complete headers
requestTimeout300000 ms (5 minutes)Time to receive the entire request
keepAliveTimeout5000 msIdle time between requests on a socket
timeout0 (none)Socket inactivity
maxHeadersCount1000Number of incoming headers
connectionsCheckingInterval30000 msHow often incomplete requests are checked

These values are from the Node.js http documentation. On expiry of the header or request timeout, the server responds with status 408 and closes the connection, without calling your request listener. The documentation also says to keep requestTimeout non zero, for example 120 seconds, to protect against denial of service when the server runs without a reverse proxy in front.

Note the history: server.timeout used to be 120 seconds and became 0 in Node 13. The requestTimeout default changed from none to 5 minutes in Node 18. Older runtimes behave differently, so check your version.

Why slow clients are a problem

A connection costs a socket and some memory even when it sends one byte a second. Open enough of them and legitimate users cannot connect. Timeouts bound how long any single connection can hold a slot without finishing its work.

Steps to tighten them

  1. Put a reverse proxy in front, and set its client header and body timeouts first. See do you need a reverse proxy in front of Node.
  2. Set headersTimeout and requestTimeout to values that fit your largest legitimate upload on your slowest realistic connection. For a JSON API, 30 to 60 seconds is often plenty.
  3. Keep headersTimeout at or below requestTimeout.
  4. Set keepAliveTimeout above your load balancer's idle timeout so Node does not close connections the balancer thinks are alive. Check your balancer's documentation for its value.
  5. Load test with a slow sender to confirm you get a 408, not a hang.
const http = require('node:http');

const server = http.createServer(app);
server.headersTimeout = 20000;
server.requestTimeout = 60000;
server.keepAliveTimeout = 65000;
server.listen(3000);

Frameworks pass these through. Fastify, for example, exposes requestTimeout and connectionTimeout in its server options, both defaulting to 0, and recommends a non zero requestTimeout when no reverse proxy is present.

What timeouts do not do

They do not limit body size or request rate. Pair them with a body limit (Express, Fastify) and rate limiting. Uploads that legitimately take longer than your timeout need a separate path or a direct to storage upload.

Safeguard's DAST web app scan and dependency scanning cover the application layer, while timeouts belong to your runtime and proxy configuration. A free scan is at gold.safeguard.sh/scan.

Quick check

Is server.timeout the setting that stops slowloris style attacks?

Not on its own. It defaults to 0 and measures socket inactivity. The header and request timeouts target slow header and body delivery.

What status code does a timed out request get?

The documentation says the server responds with 408 and closes the connection, without forwarding the request to your handler.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.