Skip to content

HTTP Keep-Alive

1. What is it? (2-3 lines)

HTTP Keep-Alive (Persistent Connection) is an HTTP header configuration (Connection: keep-alive) that instructs client and server endpoints to reuse a single open TCP/TLS connection to send and receive multiple sequential HTTP requests/responses, avoiding connection teardown and re-establishment overhead.

2. Why does it exist?

In original HTTP/1.0, every single HTTP request required opening a brand-new TCP connection (3-Way Handshake + TLS Handshake) and closing it immediately (Connection: close). For modern web applications loading 50+ images/CSS/API assets, establishing 50 separate TCP/TLS connections adds seconds of network handshake latency (\(1-3\text{ RTTs}\) per request) and overwhelms server socket memory.

3. Where is it used?

  • Web Browsers & Servers: Default behavior in HTTP/1.1 and HTTP/2 (Nginx, Apache, Node.js, Spring Boot).
  • Microservices & API Clients: Persistent HTTP client pools (Apache HttpClient, Go http.Transport, Axios).
  • Reverse Proxies & API Gateways: Keeping persistent backend connection pools to microservice pods.

4. How does it work? (simple flow)

  1. Initial Setup: Client sends HTTP request with Connection: keep-alive header \(\to\) Executes TCP 3-Way Handshake + TLS Handshake (1-3 RTT cost).
  2. Request 1 Execution: Client sends GET /api/v1/user over TCP connection \(\to\) Server returns 200 OK \(\to\) TCP Connection remains OPEN in ESTABLISHED state!
  3. Request 2 Reuse: Client sends GET /api/v1/orders over the EXACT SAME open TCP socket \(\to\) Zero Handshake Latency!
  4. Timeout / Closure: If connection stays idle past Keep-Alive: timeout=5, max=1000 limit, server or client sends Connection: close and closes socket.

5. Advantages

  • Eliminates 1-3 RTT connection handshake latency for subsequent HTTP requests.
  • Reduces CPU usage on servers (avoids repeated RSA/ECDHE asymmetric TLS key handshakes).
  • Reduces network congestion and kernel socket memory usage (TIME_WAIT socket churn).

6. Limitations

  • Idle Socket Memory Drain: Keeping thousands of idle TCP connections open consumes server RAM (socket buffers) and file descriptors (NOFILE).
  • HTTP/1.1 Head-of-Line (HoL) Blocking: HTTP/1.1 over Keep-Alive processes requests strictly one-at-a-time sequentially. If Request 1 stalls, Requests 2 and 3 block behind it! (Solved by HTTP/2 multiplexing).

7. Common interview questions (10)

  1. How does HTTP Keep-Alive differ between HTTP/1.0, HTTP/1.1, and HTTP/2?
  2. What is Head-of-Line (HoL) Blocking in HTTP/1.1 persistent connections?
  3. How do you configure keepalive_timeout and keepalive_requests in Nginx for optimal performance?
  4. What happens if a backend microservice behind Nginx doesn't enable HTTP Keep-Alive?
  5. How does HTTP Keep-Alive interact with Load Balancer idle timeouts?
  6. How does Connection Pooling use HTTP Keep-Alive underneath the hood?
  7. What is the impact of HTTP Keep-Alive on server socket TIME_WAIT state build-up?
  8. How does HTTP/2 Multiplexing eliminate the Head-of-Line blocking inherent in HTTP/1.1 Keep-Alive?
  9. How does Keep-Alive handle server-side graceful shutdown without dropping active client connections?
  10. What is the difference between TCP Keep-Alive (SO_KEEPALIVE) and HTTP Keep-Alive?

8. Common misconceptions

  • Misconception: HTTP Keep-Alive is the same as TCP Keep-Alive (SO_KEEPALIVE). Fact: HTTP Keep-Alive keeps persistent application connections open for request reuse. TCP Keep-Alive is an OS network kernel probe detecting dead TCP sockets.
  • Misconception: HTTP/1.1 Keep-Alive streams multiple requests in parallel over 1 socket. Fact: HTTP/1.1 can only execute requests sequentially. Parallel multiplexing requires HTTP/2.

10. 30-second cheat sheet

  • Header: Connection: keep-alive (Default in HTTP/1.1).
  • Core Benefit: Reuses existing TCP/TLS socket for multiple HTTP requests \(\implies\) Eliminates 1-3 RTT handshake latency!
  • HTTP/1.1 Flaw: Sequential processing only \(\implies\) Vulnerable to Head-of-Line (HoL) Blocking.
  • HTTP/2 Evolution: Replaces sequential Keep-Alive with Binary Multiplexing (parallel requests over 1 TCP connection).