🚀 HTTP/3 over QUIC

The fix for the one thing HTTP/2 couldn't touch: it throws out TCP and rebuilds reliable, multiplexed, encrypted transport on top of UDP.

Why Abandon TCP At All?

HTTP/2's remaining weakness is TCP itself. One lost segment stalls every multiplexed stream (transport head-of-line blocking). You can't fix that without changing TCP — and TCP is baked into operating-system kernels and middleboxes worldwide, so it effectively can't be changed.

The answer: build a new transport in user space, on top of UDP. UDP gives you bare packet delivery with no ordering guarantees — a blank canvas. That transport is QUIC. HTTP/3 is simply "HTTP semantics mapped onto QUIC."

flowchart TB subgraph H2["HTTP/2 stack"] A2["HTTP/2 framing"] --> T2["TLS"] --> TCP["TCP"] --> IP2["IP"] end subgraph H3["HTTP/3 stack"] A3["HTTP/3 framing"] --> Q["QUIC (streams + TLS 1.3 + loss recovery)"] --> UDP["UDP"] --> IP3["IP"] end

Independent Streams: The Core Payoff

QUIC understands streams natively. Loss recovery is per-stream, not per-connection. A lost packet carrying stream 1's data only blocks stream 1 — streams 3, 5, and 7 keep being delivered to the application. The transport-layer HOL blocking is gone.
flowchart LR L["Lost packet (stream 1)"] --> S1["Stream 1: waits for retransmit"] L -.no effect.-> S3["Stream 3: keeps flowing ✅"] L -.no effect.-> S5["Stream 5: keeps flowing ✅"]

This is the whole reason HTTP/3 exists. On a clean network HTTP/3 and HTTP/2 perform similarly; the gap opens on lossy or high-latency links (mobile, congested Wi-Fi) where independent streams shine.

Encryption Is Not Optional

QUIC has TLS 1.3 built into the transport — there is no unencrypted QUIC. Where HTTP/2-over-TLS layers TLS on top of TCP as a separate handshake, QUIC fuses the transport and cryptographic handshakes into one. See TLS for the handshake itself.

Fused handshake = fewer round trips. Establishing a TCP+TLS connection classically costs a TCP handshake then a TLS handshake — two sequential round-trip groups. QUIC combines them, so a fresh connection is typically 1-RTT, and a resumed one can be 0-RTT.

0-RTT Resumption

If the client has talked to this server before, it can cache the crypto parameters and send application data in the very first packet — no waiting for a handshake to complete.

The catch — replay risk. 0-RTT data can be captured and replayed by an attacker, so it must only carry idempotent, safe requests (a GET, never a POST /pay). This is the same idempotency reasoning from HTTP 101, now with security teeth.

Connection Migration

TCP connections are glued to the 4-tuple (source IP, source port, dest IP, dest port). Walk out of Wi-Fi onto cellular and your IP changes — the TCP connection dies and everything restarts.
QUIC identifies a connection by a Connection ID, not the IP/port. When your network changes, the connection migrates — the same session continues on the new path with no re-handshake and no dropped downloads. This is a genuinely new capability, not just a speed tweak.

QPACK: HPACK for an Unordered World

HPACK assumed a single ordered TCP stream. QUIC streams can arrive out of order, so a dynamic-table design that assumed ordering would reintroduce HOL blocking (a header on stream 5 waiting for a table update on stream 1).

QPACK redesigns header compression to tolerate reordering: it separates table updates onto dedicated streams and lets the encoder choose how much it's willing to block, trading a little compression for independence.

Discovery: How Clients Find HTTP/3

A browser can't just assume UDP works (some networks block it). HTTP/3 is discovered via Alt-Svc: a server answering over HTTP/1.1 or /2 advertises an HTTP/3 endpoint, and the client upgrades on the next visit. It also keeps a TCP fallback ready.

HTTP/2 200 OK
alt-svc: h3=":443"; ma=86400
Real-world: because UDP is sometimes throttled or blocked by middleboxes, production deployments run HTTP/3 and keep HTTP/2 as a fallback. You rarely pick one; you offer both and let clients negotiate.

Key Takeaways

QUIC featureFixes / enables
UDP + user-space transportDeployable without kernel/middlebox changes
Per-stream loss recoveryNo transport-layer HOL blocking
Built-in TLS 1.3Always encrypted; fused handshake
0-RTT resumptionSend data on the first packet (idempotent only)
Connection IDsSurvive network changes (migration)
QPACKHeader compression that tolerates reordering
The through-line: HTTP/1.1 → /2 → /3 is one long fight against head-of-line blocking, chased down from the application layer, to TCP, and finally out of TCP entirely. Read that deep-dive next to see all three layers side by side.