HTTP/2 & HTTP/3
Multiplexing streams, HPACK/QPACK header compression, server push, QUIC UDP transport, and 0-RTT connection resumption.
Overview
Overview HTTP/2 and HTTP/3 are major protocol revisions designed to address the performance limitations of HTTP/1.1. Understanding them is critical for engineers working on high-performance web services, CDNs, API gateways, and load balancers.
HTTP/2, standardized in RFC 7540, introduced binary framing as a replacement for HTTP/1.1's text-based format. Requests and responses are split into frames, which are multiplexed over a single TCP connection using stream IDs. This eliminates the need for multiple TCP connections to parallelize requests (HTTP/1.1 required 6 parallel connections per origin in browsers). HTTP/2 also introduced HPACK header compression, which significantly reduces header overhead for APIs that send the same headers repeatedly, and server push, which allows the server to proactively send resources the client will need before it asks.
However, HTTP/2 still runs over TCP, which means it inherits TCP's head-of-line blocking at the transport layer. A single lost packet stalls all multiplexed streams until the retransmission arrives. On lossy networks, HTTP/2 can perform worse than HTTP/1.1 with 6 parallel connections because HTTP/1.1's parallel connections are independent TCP streams that do not block each other.
HTTP/3, standardized in RFC 9114, solves this by running over QUIC instead of TCP. QUIC is a UDP-based transport that implements reliable delivery per-stream — a lost packet only stalls the stream it belongs to, not all streams. QUIC also integrates TLS 1.3 natively, reducing connection establishment to 1 RTT (or 0 RTT for resumed connections). Connection migration allows QUIC connections to survive IP address changes (e.g., switching from WiFi to LTE on mobile), which is impossible with TCP-based protocols.
For production systems, HTTP/3 support requires that UDP port 443 is not firewalled, and servers must advertise HTTP/3 availability via the Alt-Svc response header. Clients that cannot use QUIC fall back to HTTP/2 transparently. Major CDNs (Cloudflare, Fastly, Google Cloud) and servers (nginx, Caddy, Envoy) support HTTP/3, making it increasingly relevant for SRE and infrastructure teams.
Key concepts
- HTTP/2 Streams and Frames
- In HTTP/2, a stream is a bidirectional sequence of frames on a single TCP connection. Each stream has a unique integer ID (odd IDs for client-initiated, even for server-initiated). Frames are the unit of communication: HEADERS, DATA, PRIORITY, RST_STREAM, SETTINGS, PUSH_PROMISE, PING, GOAWAY, WINDOW_UPDATE, CONTINUATION. Multiple streams are multiplexed over one connection, with per-stream flow control via WINDOW_UPDATE frames.
- HPACK Header Compression
- HTTP/2's header compression format (RFC 7541). Maintains a dynamic table on both client and server of recently seen headers. Headers can be sent as indices into a static table (common headers like :method, :path, :status pre-defined), dynamic table references, or literal values with or without table insertion. Eliminates the repetitive overhead of large Cookie and Authorization headers sent on every request.
- QPACK
- HTTP/3's header compression format (RFC 9204), designed to work with QUIC's out-of-order stream delivery. HPACK cannot be used with QUIC because HPACK assumes in-order delivery: referencing a dynamic table entry that was inserted in a not-yet-received earlier request would cause a decoding error. QPACK separates the encoder/decoder streams from the request streams and uses a required-insert-count mechanism to handle out-of-order delivery safely.
- Server Push
- An HTTP/2 feature allowing servers to send resources to clients before they are requested. The server sends a PUSH_PROMISE frame containing the request headers for the resource it will push, then sends the resource in a new server-initiated stream. In practice, server push proved difficult to use correctly and has been removed from Chrome in 2022. HTTP/3 does not support server push.
- 0-RTT Connection Resumption
- A QUIC/TLS 1.3 feature enabling a client to send application data in the first packet of a resumed connection, bypassing the handshake round-trip. The server provides a session ticket containing resumption keys at the end of the previous connection. On reconnect, the client includes early data in its first message. Restriction: 0-RTT data is not forward-secret and is replay-vulnerable; it should only carry idempotent read requests.
- Connection Migration
- A QUIC feature that decouples connection identity from the network 4-tuple (src IP, src port, dst IP, dst port). QUIC connections are identified by connection IDs exchanged during the handshake. If a client's IP or port changes (mobile switching from WiFi to LTE, NAT rebinding), it can send a path challenge on the new path. The server validates it and continues the connection without renegotiation. TCP connections are always bound to the 4-tuple and are disrupted by any address change.
When to use it
- Evaluating whether to enable HTTP/3 on an nginx or Caddy load balancer
- Debugging why HTTP/2 performance degrades on lossy mobile networks
- Configuring a CDN or API gateway for maximum throughput to global clients
- Explaining to an interviewer why HTTP/2 multiplexing did not fully solve the HOL blocking problem
- Implementing gRPC services (which use HTTP/2 framing) and understanding its transport constraints
- Analyzing pcap or tcpdump traces to identify HTTP/2 stream multiplexing behavior
Interview questions
- How does HTTP/2 multiplexing work, and why does it not fully eliminate head-of-line blocking?
- What is QUIC and how does HTTP/3 use it? What are the tradeoffs vs HTTP/2?
Sign up free to read the full topic
More Networking topics
Start free on Cariara · Coding problems · System design studio