Chapter 30 — HTTP/2 and HTTP/3
In one sentence
HTTP/2 sends many requests at once over a single TCP connection, and HTTP/3 moves to a new transport over UDP to fix the one problem HTTP/2 couldn't.
The problem HTTP/2 solved
HTTP/1.1 can only handle one request at a time per connection. A modern web page needs 50–100 resources. So browsers opened ~6 connections per site and queued everything — each connection paying its own TCP + TLS handshake, and each request waiting for the one before it ("head-of-line blocking" at the HTTP layer).
What HTTP/2 does
HTTP/1.1 HTTP/2
6 connections, one request ONE connection, many
at a time each requests interleaved
conn1: [req A......][req D...] conn: [A][B][C][A][B][D][C][A]...
conn2: [req B........] \_______________________/
conn3: [req C.....] all mixed together,
... reassembled at the other end
Key features:
- Multiplexing — many requests in flight on one connection, interleaved.
- Header compression (HPACK) — repeated headers (cookies, user-agent) cost ~1 byte instead of hundreds.
- Binary framing instead of text — faster to parse, less ambiguous.
- Stream priorities — tell the server the CSS matters more than the footer image.
Result: usually much faster, and it made "domain sharding" and sprite sheets obsolete.
The problem HTTP/2 couldn't solve
Everything is on one TCP connection. And TCP guarantees in-order delivery of the whole byte stream. So:
If ONE packet is lost, TCP holds back EVERYTHING behind it --
including data belonging to completely unrelated requests.
[req A data][req B data][LOST][req C data][req D data]
^
everything after this waits,
even though C and D arrived fine
This is TCP head-of-line blocking. On a clean network HTTP/2 is great. On a lossy one (mobile, congested Wi-Fi), it can be worse than HTTP/1.1's six independent connections, because with six connections a loss only stalls one of them.
What HTTP/3 does
HTTP/3 runs over QUIC, a new transport protocol built on UDP.
Wait — UDP? The unreliable one? Yes, but QUIC implements its own reliability per stream:
QUIC streams are INDEPENDENT.
A lost packet for stream B stalls ONLY stream B.
Streams A, C, and D carry on.
Plus:
| Feature | Benefit |
|---|---|
| Encryption and transport handshake merged | 1 round trip to set up (or 0 on a repeat visit) instead of TCP+TLS's 2–3 |
| Connection ID instead of the 4-tuple | Your connection survives changing networks — walk out of Wi-Fi onto mobile and the download continues |
| Always encrypted | No unencrypted QUIC exists |
| Implemented in the application, not the kernel | Can be improved without OS upgrades — which is why it's built on UDP |
Why build it on UDP? Because middleboxes on the internet only really understand TCP and UDP. Inventing a genuinely new protocol number would have been blocked everywhere. UDP is the escape hatch that let a new transport be deployed.
Which version are you using?
Browsers negotiate automatically: TLS's ALPN picks HTTP/2, and an Alt-Svc
header or DNS HTTPS record advertises HTTP/3 for next time. If UDP is blocked,
it falls back.
Practice (20 min)
A. Check what a site supports:
curl -sI --http2 https://example.com | head -1 # "HTTP/2 200"
curl -sI --http1.1 https://example.com | head -1 # "HTTP/1.1 200"
curl -sI --http3 https://cloudflare.com | head -1 # needs curl built with HTTP/3
B. Look for the HTTP/3 advertisement:
curl -sI https://cloudflare.com | grep -i alt-svc
dig cloudflare.com HTTPS +short # look for alpn="h3"
C. See QUIC traffic on your machine. You're probably already using it:
sudo tcpdump -i any -n 'udp port 443'
Browse a Google or Cloudflare-fronted site. That UDP traffic on 443 is HTTP/3.
D. Compare in your browser. DevTools → Network → right-click the column
headers → enable Protocol. Reload a few sites and see h2, h3, and
http/1.1 in the wild.
E. See multiplexing: in DevTools, look at the waterfall for an HTTP/2 site. Notice many requests starting at nearly the same moment, rather than in batches of six.
Common confusions
- "HTTP/3 uses UDP so it's unreliable." QUIC adds reliability on top, per stream. It's as reliable as TCP, with better loss behaviour.
- "Should I upgrade my site to HTTP/2?" If you use a CDN or a modern web server, you probably already have it. It's essentially free.
- "Is HTTP/1.1 dead?" No — it's simple, universal, and fine for APIs and server-to-server calls. It's browsers loading complex pages that benefit most from H2/H3.
Check yourself
- What was the main limitation of HTTP/1.1 that HTTP/2 fixed?
- What is TCP head-of-line blocking, and why does it hurt HTTP/2 specifically?
- Why is QUIC built on UDP rather than being a brand-new protocol?
- What does "connection migration" mean and why is it useful?
Further reading
- Book (free): High Performance Browser Networking, Chapters on HTTP/2 — hpbn.co. Still the clearest explanation.
- Article: "HTTP/3: From root to tip" and "The Road to QUIC" — Cloudflare blog. Excellent and readable.
- Video: "HTTP/1 vs HTTP/2 vs HTTP/3" — Hussein Nasser (he has a whole playlist on this) or ByteByteGo's animated version.
- Spec: RFC 9114 (HTTP/3) and RFC 9000 (QUIC) — for later.
End of Part 7 — Milestone check
- I have typed an HTTP request by hand with
nc - I know the meaning of the 2xx/3xx/4xx/5xx families
- I can explain why keep-alive matters
- I can explain the three guarantees of TLS and how certificates work
- I have inspected a real certificate with
openssl - I can explain head-of-line blocking and how HTTP/3 avoids it