HTTP Protocol Evolution: HTTP/1.1, HTTP/2, HTTP/3, and QUIC

The Hypertext Transfer Protocol (HTTP) is the foundational application protocol of the World Wide Web. Over three decades, HTTP has evolved from simple text-based single-request connections (HTTP/1.0) to binary multiplexed streams (HTTP/2) and UDP-based encrypted transport with zero-round-trip resumption (HTTP/3).


⚡ Quick Dive

HTTP Protocol Generations Comparison

Feature HTTP/1.1 (1997) HTTP/2 (2015) HTTP/3 (2022)
Transport Layer TCP (+ optional TLS) TCP + TLS 1.2 / 1.3 QUIC (over UDP) + TLS 1.3
Format Plain Text (ASCII) Binary Framing Binary Framing
Multiplexing ❌ (1 request per TCP socket) ✅ (Multiple streams over 1 TCP) ✅ (Truly independent UDP streams)
Head-of-Line Blocking Application & Transport level Transport (TCP packet drop halts all) Completely Eliminated
Header Compression ❌ (Plain text headers repeat) HPACK (Static/Dynamic table) QPACK (Out-of-order safe)
Handshake Latency 2-3 RTT (TCP + TLS) 2-3 RTT (TCP + TLS) 0-RTT to 1-RTT
Connection Migration ❌ (Broken when IP changes) ❌ (Broken when IP changes) Connection IDs survive network switch

📖 Extended Guide

1. HTTP/1.1 & The Head-of-Line Blocking Problem

In HTTP/1.1, requests and responses are sent as plain text. Browsers could only execute one request at a time per TCP connection:

  • To load 50 assets on a page, browsers were forced to open 6 parallel TCP connections per domain.
  • Developers used workarounds: Domain Sharding (static1.example.com, static2.example.com), CSS Sprites, and JavaScript Bundling.

2. HTTP/2: Binary Framing & True Multiplexing

HTTP/2 introduced the Binary Framing Layer, breaking requests into independent frames (HEADERS, DATA, SETTINGS) tagged with unique Stream IDs:

Single TCP Connection:
Client ══════════════════════════════════════════════════════════════════════► Server
  [ Stream 1: Header ] [ Stream 3: Data ] [ Stream 1: Data ] [ Stream 5: Header ]
  (Interleaved frames stream concurrently without blocking each other)
  • HPACK Compression: Headers (e.g. User-Agent, Cookie) are compressed using static and dynamic lookup tables, reducing header overhead by up to 85%.

3. HTTP/3: The QUIC Revolution

While HTTP/2 multiplexed streams at the application layer, they still traveled over a single TCP stream. If a single packet was lost in transit, the operating system kernel paused all streams until retransmission completed.

HTTP/3 replaces TCP with QUIC over UDP:

HTTP/3 over QUIC:
Stream 1 (UDP) ───[ Packet Loss! ] ──► (Stream 1 retransmits independently)
Stream 2 (UDP) ──────────────────────► (Stream 2 delivers instantly to browser without delay!)

Connection Migration:

When a mobile device switches from Wi-Fi to Cellular (4G/5G), its IP address changes.

  • In HTTP/1.1 and HTTP/2, all active TCP connections drop and must be re-negotiated.
  • In HTTP/3, the connection is bound to a 64-bit Connection ID; active downloads and video streams continue without interruption.

4. Configuring HTTP/2 and HTTP/3 in Nginx

server {
    # Listen on port 443 with TLS and HTTP/2
    listen 443 ssl http2;
    
    # Listen on port 443 with QUIC (HTTP/3) over UDP
    listen 443 quic reuseport;
    
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Advertise HTTP/3 support to clients via Alt-Svc header
    add_header Alt-Svc 'h3=":443"; ma=86400';

    location / {
        root /var/www/html;
        index index.html;
    }
}