Glossary Term
Keep-Alive (Persistent Connections)
Keep-alive reuses one TCP connection for many HTTP requests. Learn the HTTP/1.1 default, idle timeout defaults in nginx and Node, and why mismatches cause 502s.
TL;DR: Keep-alive means reusing one TCP connection for multiple HTTP requests. It has been the HTTP/1.1 default since the start; the risk now is a timeout mismatch between two hops, which shows up as random 502s.
Keep-alive, formally a persistent connection, is HTTP/1.1 behavior in which the connection stays open after a response so further requests can reuse it instead of paying for a new TCP and TLS handshake. In HTTP/1.0 you had to opt in with Connection: keep-alive; in HTTP/1.1 you opt out with Connection: close.
On the wire
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 27
Connection: keep-alive
Keep-Alive: timeout=5
In HTTP/1.1 the Connection header here is redundant. The Keep-Alive header is an advisory hint that RFC 9110 and 9112 do not define; support is inconsistent. Persistence also requires the message length to be known, through Content-Length or chunked encoding, so the client knows where one response ends.
Defaults worth knowing
- nginx:
keepalive_timeout 75sfor clients. Connections to upstreams are not kept alive unless you configureproxy_http_version 1.1, an emptyConnectionheader and anupstreamkeepalivepool. - Apache:
KeepAliveTimeout 5seconds. - Node.js:
server.keepAliveTimeoutdefaults to 5000 ms in current releases (still true in Node 26.10). A change merged upstream raises the default to 65000 ms in a future release, so set it explicitly rather than relying on your version’s default.
Non-obvious facts
- The 502 race. If a load balancer’s idle timeout (60 seconds by default on an AWS ALB) is longer than the backend’s, the backend can close a connection at the same moment the balancer reuses it. The balancer sees a reset and returns 502. Set the backend’s keep-alive timeout above the balancer’s idle timeout; in Node, raise
keepAliveTimeout(and keepheadersTimeoutabove it). - Reuse saves round trips. A new HTTPS connection costs a TCP handshake plus a TLS handshake before the first byte of the request.
- Retries on a dead connection are only safe for idempotent requests. If the connection was closed, a client may resend a
GETautomatically, but aPOSTis not safely repeatable; see idempotent. - HTTP/1.1 reuse is serial. Each connection handles one request at a time, which is why browsers open several per host. HTTP/2 removes that limit.
- Idle connections cost memory. Long timeouts on a busy server pin file descriptors, so the default is a trade-off, not a free win.
Go deeper
Frequently asked questions
What is HTTP keep-alive?
It is connection reuse: after a response finishes, the TCP (and TLS) connection stays open so the next request skips the handshakes. It is the default in HTTP/1.1.
How do I turn keep-alive off?
Send Connection: close on the request or response. After that message, the connection is closed.
Does HTTP/2 use the Keep-Alive header?
No. HTTP/2 and HTTP/3 multiplex requests over one long-lived connection, and connection-specific headers such as Keep-Alive and Connection are not allowed there.
Why do I get intermittent 502 errors behind a load balancer?
Often the backend closes idle connections sooner than the load balancer expects, so the balancer sends a request on a connection that was just closed. Make the backend idle timeout longer than the balancer's.
Sources
Related
Keep-Alive Header
Learn how the Keep-Alive header controls HTTP connection persistence and reuse. Reduce latency and improve performance by avoiding repeated TCP handshakes.
ERR_CONNECTION_RESET and ECONNRESET: Find the RST
Fix ERR_CONNECTION_RESET, ECONNRESET and curl (56) Connection reset by peer: keep-alive races, body limits, firewalls, crashes. Find who sent the RST.
nginx 502 Bad Gateway: Causes and Fixes by Error Log
Fix nginx 502 Bad Gateway by matching the error log: connection refused, prematurely closed connection, php-fpm socket permissions, too big header, keepalive.
Request and Response Lifecycle
Learn how HTTP requests travel from browser to server and back. Understand DNS resolution, TCP connections, request/response flow, and the complete lifecycle.