HTTP/3 and QUIC

TL;DR / HTTP/3 replaces TCP with QUIC (a UDP-based transport protocol), eliminating TCP's head-of-line blocking so a single lost packet only stalls the affected stream, not all streams on the connection.

How It Works

 HTTP/2 + TCP                      HTTP/3 + QUIC

 ┌──────────────┐                  ┌──────────────┐
 │   Stream 1   │                  │   Stream 1   │
 └──────────────┘                  └──────────────┘
 ┌──────────────┐                  ┌──────────────┐
 │   Stream 2   │ TCP loss ->      │   Stream 2   │ UDP loss ->
 └──────────────┘ ALL blocked      └──────────────┘ only Stream 2
 ┌──────────────┐                  ┌──────────────┐ blocked
 │   Stream 3   │                  │   Stream 3   │
 └──────────────┘                  └──────────────┘

Edit diagram

HTTP/2 solved application-layer head-of-line blocking by multiplexing multiple logical streams over a single TCP connection. But TCP itself has no concept of streams. To TCP, all data on a connection is a single ordered byte stream. When a TCP packet is lost, the operating system's TCP implementation buffers all subsequent packets until the lost one is retransmitted and received. Every HTTP/2 stream stalls, even those whose data was not lost. This is transport-layer head-of-line blocking, and it can make HTTP/2 perform worse than HTTP/1.1's multiple parallel connections on lossy networks.

QUIC's Architecture

QUIC (Quick UDP Internet Connections) is a transport protocol built on UDP. It implements reliability, ordering, congestion control, and encryption -- everything TCP provides -- but with a critical difference: streams are independent at the transport layer. Each QUIC stream has its own flow control and retransmission logic. A lost packet for stream 2 triggers retransmission for stream 2 only. Streams 1 and 3 continue receiving and processing data uninterrupted.

QUIC integrates TLS 1.3 directly into the transport handshake. A TCP+TLS connection requires two or three round trips before data can flow: one for TCP's three-way handshake, then one or two for TLS negotiation. QUIC combines the transport and cryptographic handshakes into a single round trip for new connections. For connections to servers the client has previously visited, QUIC supports 0-RTT resumption -- the client sends application data in the very first packet.

Connection Migration

TCP connections are identified by the 4-tuple: source IP, source port, destination IP, destination port. When a mobile device switches from Wi-Fi to cellular, its source IP changes and all TCP connections die.

QUIC connections are identified by a connection ID, not by IP addresses. When the network changes, the client sends packets from the new IP with the same connection ID. The server recognizes the connection and continues without a reset. This is particularly significant for mobile users who frequently transition between networks.

HTTP/3 over QUIC

HTTP/3 is the HTTP protocol adapted for QUIC. The mapping is relatively straightforward: each HTTP request-response exchange uses a QUIC stream. Header compression uses QPACK (adapted from HTTP/2's HPACK but designed for QUIC's out-of-order delivery). Server push exists in the spec but is rarely implemented and is being deprecated.

The major behavioral difference from HTTP/2 is that QUIC streams do not share a single congestion window in the same way TCP does. QUIC's congestion control operates at the connection level, but individual stream flow control prevents a slow stream from consuming all available bandwidth. This means a large image download does not starve a small API request sharing the same connection.

Performance Characteristics

On reliable, low-latency networks (wired connections in data centers), HTTP/3 offers modest improvements -- primarily the faster handshake. On lossy, high-latency networks (mobile, congested Wi-Fi, intercontinental connections), HTTP/3 can be transformative. Studies from Cloudflare and Google show significant improvements in tail latency (95th and 99th percentile page load times) on these networks. The median improvement is small, but the worst-case performance improves dramatically because packet loss no longer cascades across all requests.

The 0-RTT handshake benefit is most visible for short-lived connections. An API call that requires a new connection completes one full round trip faster with QUIC. For long-lived connections, the handshake cost is amortized and less significant.

Deployment and Frontend Impact

HTTP/3 requires UDP port 443 to be open. Some corporate firewalls and ISPs block or deprioritize UDP traffic. Browsers discover HTTP/3 support through the Alt-Svc HTTP header or DNS HTTPS records (SVCB/HTTPS). The initial connection typically uses HTTP/2 over TCP, and the browser upgrades to HTTP/3 on subsequent requests after receiving Alt-Svc.

If QUIC packets are consistently blocked, browsers fall back to HTTP/2 over TCP transparently. This means HTTP/3 deployment is safe: users on networks that cannot support QUIC simply use TCP as before. Most major CDNs support HTTP/3 as a configuration toggle. Origin servers do not need to support it; the CDN terminates QUIC at the edge.

From a frontend perspective, HTTP/3 is largely transparent -- you do not write different code. However, understanding QUIC informs architectural decisions: bundling multiple small requests into one large request (a common HTTP/1.1 optimization) is less necessary, because multiplexing actually works without head-of-line blocking. This strengthens the case for granular code splitting and many small API calls over few large ones.

Gotchas

  • 0-RTT data can be replayed -- an attacker who captures a 0-RTT packet can resend it. Servers must ensure 0-RTT requests are idempotent. Most implementations limit 0-RTT to GET requests and safe methods only.
  • QUIC is not "faster TCP" -- on low-loss networks, QUIC's overhead (encryption, connection IDs, UDP userspace processing) can make it marginally slower than optimized TCP. The win is on lossy networks and connection establishment.
  • Corporate firewalls may block UDP 443 -- browsers fall back to TCP automatically, but users behind such firewalls never benefit from HTTP/3. There is no way for the developer to force QUIC usage.
  • QUIC congestion control runs in user space, not kernel space -- this means CPU usage is higher than TCP for the same throughput. Server-side QUIC implementations are more resource-intensive than TCP equivalents.
  • The Alt-Svc discovery mechanism means the first page load is always HTTP/2 -- browsers need to learn about HTTP/3 support before they can use it. DNS HTTPS records (SVCB) can eliminate this first-load penalty but require DNS infrastructure support.