HTTP/2, HTTP/3 and QUIC

The HTTP you learned — plain text, one request, one response — is HTTP/1.1, and it powered the web for two decades. But the web it was designed for was a handful of documents. Today's web page pulls hundreds of resources — scripts, fonts, images, trackers — and HTTP/1.1 fetches them like someone posting letters one at a time and waiting for each reply before sending the next. That serial bottleneck is the story of this page: how HTTP/2 and then HTTP/3 (over a new transport called QUIC) tore it down, and the subtle reason the first fix wasn't enough.

The villain has a name that recurs at every level of networking: head-of-line (HOL) blocking — one stuck item at the front of a queue holding up everything behind it, even though those things are perfectly ready to go. Watch how each protocol version chases HOL blocking to a deeper and deeper layer.

HTTP/1.1's problem: one conversation at a time

On a single HTTP/1.1 connection, requests are strictly serial: send request 1, wait for response 1, then send request 2. If response 1 is a slow 2 MB image, requests 2 and 3 — maybe tiny, maybe already ready on the server — sit idle behind it. That's application-layer HOL blocking.

Browsers hacked around it in two ugly ways. They opened 6 parallel TCP connections per site (6 lanes instead of 1) — but each connection has its own handshake and congestion-control warm-up, and 6 is an arbitrary, small cap. And developers resorted to bundling — jamming all scripts into one giant file, stitching images into sprite sheets — purely to dodge the per-request cost. On top of this, every HTTP/1.1 request re-sends the same verbose headers (cookies, user-agent, accept lines) as plain text, uncompressed, thousands of times. The protocol was drowning in its own overhead.

HTTP/2: many streams, one connection

HTTP/2 (2015) kept HTTP's meaning — same methods, same status codes, same headers — but completely rebuilt how it's put on the wire. Three changes matter:

This solves application-layer HOL blocking: at the HTTP level, streams are independent and a slow response no longer blocks the others. But HTTP/2 left one deeper problem untouched, and it's the crux of the whole page.

Three protocols, one picture

The diagram lays the three approaches side by side on a shared time axis. Step through it to see the serial stall of HTTP/1.1, HTTP/2's multiplexing (and how one lost packet still freezes every stream), and how HTTP/3 finally isolates a loss to a single stream.

QUIC: move the streams off TCP entirely

The fix for transport HOL blocking is radical: stop using TCP. HTTP/3 runs over QUIC, a new transport built by Google (now an IETF standard) that runs on top of UDP — the connectionless, no-ordering-guarantees protocol. On bare UDP that would be chaos, so QUIC rebuilds the good parts of TCP (reliability, congestion control, ordering) per stream, in user space, while deliberately leaving out the one bad part: a single global order for the whole connection.

Because QUIC understands streams natively, a lost packet on stream A stalls only stream A; streams B and C, whose packets arrived, are delivered immediately. That is the payoff HTTP/2 couldn't reach — true per-stream independence. QUIC piles on more wins from being new and in user space:

And HTTP/3 is simply HTTP semantics carried over QUIC: the same methods, status codes and headers you already know, now on a transport that doesn't let one lost packet block everything else.

TCP lives in the operating-system kernel, and the whole Internet — every router, firewall and middlebox — has 40 years of assumptions baked in about how TCP behaves. Changing TCP means changing billions of kernels and untold middleboxes; in practice, impossible. UDP, by contrast, is a thin "here's a packet" primitive that middleboxes already pass through. By building on UDP in user space (inside the browser and server application, not the kernel), QUIC can be deployed and updated as fast as a browser auto-update — no waiting a decade for operating systems to catch up. It's protocol evolution routed around an ossified Internet.

The single most common misunderstanding here is "HTTP/2 has multiplexing, so it fixed head-of-line blocking." It fixed one of them. At the application layer, yes: HTTP/2's streams are independent, so a slow response no longer blocks other requests. But all those streams still ride inside one TCP connection, and TCP insists on delivering its byte stream strictly in order. So the instant a single TCP packet is lost, TCP freezes delivery of every stream — including ones whose data already arrived — until the missing packet is retransmitted. That is transport-layer HOL blocking, and HTTP/2 is powerless against it because the flaw is in TCP, one layer below.

This is exactly why QUIC exists and why HTTP/3 abandoned TCP for a UDP-based transport that understands streams. If you remember one thing: multiplexing over a single ordered TCP pipe moves the HOL bottleneck down a layer; it doesn't remove it. Only a stream-aware transport (QUIC) removes it. On a fast, loss-free network HTTP/2 and HTTP/3 perform similarly — QUIC's advantage shows up precisely when packets are being lost.