We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
This idea carries a full system design question on its own. Each walks through the full answer.
System Design Masterclass · Api Design Protocols
Free preview: the first 2 parts of this 7-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Api Design Protocols
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
Every phone call starts with dialing, ringing, and "hello." If you need to ask your colleague ten questions, do you call them ten times? Dial, ring, hello, ask, hang up, repeat? No. You call once, ask all ten questions, and hang up when you are done.
Keep-alive connections work the same way for HTTP. Without keep-alive, every HTTP request opens a new connection (with a 3-way handshake), optionally performs a TLS handshake, sends the request, receives the response, and closes the connection. For the next request, the whole process repeats.
With keep-alive, the TCP connection stays open after the response. The next request reuses the same connection, skipping the handshake entirely. A TCP handshake takes 1 round trip (SYN, SYN-ACK, ACK). A TLS 1.2 handshake adds 2 more round trips (TLS 1.3 reduces this to 1). On a 100ms latency network, that is 200-300ms saved per request.
/1.1 made keep-alive the default in 1997 (RFC 2616). Every modern browser and HTTP client uses it automatically. But understanding how it works matters because misconfigured keep-alive settings are a common source of "connection reset" errors and resource leaks in production. Cloudflare's 2019 post-mortem traced a major outage to keep-alive connections being held too long after a backend was decommissioned.
Without keep-alive (/1.0 default):
Request 1: [TCP handshake] [TLS handshake] [GET /page] [Response] [Close]
Request 2: [TCP handshake] [TLS handshake] [GET /css] [Response] [Close]
Request 3: [TCP handshake] [TLS handshake] [GET /js] [Response] [Close]
// 3 handshakes = 3 * 200ms = 600ms wasted
With keep-alive (HTTP/1.1 default):
Request 1: [TCP handshake] [TLS handshake] [GET /page] [Response]
Request 2: [GET /css] [Response] <- same connection!
Request 3: [GET /js] [Response] <- same connection!
[Close after idle timeout]
// 1 handshake = 200ms, reused for all 3 requests
Configuration parameters:
| Parameter | What It Controls | Typical Value |
|---|---|---|
Keep-Alive: timeout=5 | Idle time before server closes connection | 5-120 seconds |
Keep-Alive: max=100 | Maximum requests per connection | 100-1000 |
Server keepAliveTimeout | How long server holds idle connections | 5-65 seconds |
| Connection pool size | Maximum concurrent keep-alive connections per host | 5-25 |
The idle connection trap. Keep-alive connections consume server resources (file descriptors, memory) even when idle. If 10,000 clients each maintain a keep-alive connection that sits idle 99% of the time, the server holds 10,000 open connections doing nothing. A Linux process can only hold about 1,024 file descriptors by default (tunable to 65,536+ with ulimit -n). Set reasonable idle timeouts to release unused connections.
The timeout mismatch problem. If the client's keep-alive timeout is longer than the server's, the client will try to reuse a connection the server already closed. This causes "connection reset by peer" or "ECONNRESET" errors. Nginx defaults to keepalive_timeout 75s. Node.js defaults to server.keepAliveTimeout = 5000ms. If you put Node.js behind Nginx without adjusting, the Node.js server closes connections that Nginx still considers active. Set the server timeout slightly higher than the reverse 's timeout to avoid this.