HTTP/2 vs HTTP/3: What Actually Changed
HTTP/2 fixed request multiplexing but stayed on TCP; HTTP/3 moves to QUIC over UDP to kill head-of-line blocking at the transport layer. The real differences.
HTTP/2 and HTTP/3 both solve the same problem — too many round trips to load one page — but they solve it at different layers. HTTP/2 fixed it inside HTTP itself, by multiplexing many requests over a single TCP connection. HTTP/3 goes a level deeper and replaces TCP entirely, running over a new transport called QUIC. The gap between them mostly comes down to what happens when a single packet gets lost.
Where HTTP/1.1 fell short
Before either upgrade, HTTP/1.1 sent one request at a time per connection unless the browser opened several connections in parallel (browsers typically capped this at six per host). Every additional round trip added latency, so pages leaned on workarounds — spriting images, concatenating scripts, sharding assets across domains — purely to get more parallel connections. Those hacks became the target for HTTP/2’s redesign.
HTTP/2: multiplexing over one TCP connection
HTTP/2 keeps HTTP’s semantics — methods, headers, status codes — but changes how requests travel over the wire. It introduces a binary framing layer that splits requests and responses into small frames, all interleaved over a single TCP connection. That means a browser can ask for a stylesheet, three images, and a script at the same time, on the same connection, instead of queuing them or opening new connections.
HTTP/2 also added header compression (HPACK) and server push (later mostly abandoned in practice). The result was a real jump over HTTP/1.1: fewer connections, fewer redundant headers, better use of available bandwidth. See what is a CDN for how edge caching compounds these gains further out from the origin.
The TCP problem HTTP/2 couldn’t fix
HTTP/2’s multiplexing happens above TCP, and TCP delivers bytes strictly in order. If one packet in the stream is lost, TCP holds every subsequent packet — even ones for a completely unrelated request — until the lost packet is retransmitted and arrives. This is head-of-line blocking, and multiplexing at the HTTP layer doesn’t help: the requests are independent from HTTP’s point of view but get stuck behind the same TCP queue. On networks with any meaningful packet loss (mobile networks, congested Wi-Fi), this erases much of HTTP/2’s benefit.
HTTP/3: QUIC replaces TCP
HTTP/3 addresses this by dropping TCP and running over QUIC, a transport protocol built on top of UDP. QUIC implements multiple independent streams inside the transport layer itself, so a lost packet only blocks the one stream it belonged to — every other stream keeps flowing. This is the headline fix: head-of-line blocking moves from “blocks everything” to “blocks one request.”
QUIC also folds in encryption and connection setup that TCP + TLS handle as separate steps. A fresh HTTP/3 connection typically completes its cryptographic handshake in one round trip instead of the two-plus round trips TCP + TLS usually need, and a returning client can often send data on the very first packet (0-RTT). QUIC connections are also identified by a connection ID rather than a fixed IP/port tuple, so a client switching from Wi-Fi to cellular can keep the same connection alive instead of renegotiating from scratch.
Comparing the three
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Transport | TCP | TCP | QUIC (UDP) |
| Multiplexing | None (one request per connection) | Yes, at the HTTP layer | Yes, at the transport layer |
| Head-of-line blocking | Severe | Still present (TCP-level) | Limited to the affected stream |
| Handshake | TCP + separate TLS | TCP + separate TLS | Combined in QUIC, often 1-RTT |
| Connection migration | No | No | Yes (survives network changes) |
| Header compression | None | HPACK | QPACK |
Why HTTP/3 isn’t a guaranteed win everywhere
QUIC runs in user space over UDP, which means it doesn’t get the same decades of kernel-level optimization TCP has. Some corporate firewalls and networks throttle or block UDP outright, in which case clients fall back to HTTP/2. And on a clean, low-latency connection with little packet loss, the practical difference between HTTP/2 and HTTP/3 can be small — the gains show up most on lossy or high-latency networks, which is why HTTP/3 matters most for mobile users.
Most CDNs and modern browsers negotiate the best available protocol automatically via the Alt-Svc header, so there’s rarely a reason to choose manually — the server advertises HTTP/3 support and capable clients upgrade. Deploying it is largely a matter of using infrastructure that supports it, similar to how deploying to Cloudflare Pages gets you HTTP/3 support without extra configuration. It’s also worth pairing protocol-level gains with page-level ones — see the Core Web Vitals guide for what still matters once the network stack is out of the way.
The takeaway
HTTP/2 fixed request multiplexing but left TCP’s head-of-line blocking intact. HTTP/3 fixes that by moving multiplexing into QUIC, a new transport over UDP, which also collapses the handshake and survives network changes. The upgrade is mostly invisible to developers — it’s negotiated automatically — but it matters most for users on lossy or high-latency connections, which in practice means most of the mobile web.
Keep reading
Takina · · 4 min read HTTP Range Requests and Partial Content, Explained
HTTP range requests let a client ask for just part of a resource, enabling video seeking, resumable downloads, and partial file fetches over HTTP.
Takina · · 5 min read Gzip vs Brotli: HTTP Compression Compared
Gzip and Brotli both shrink HTTP responses before they hit the wire. How each algorithm works, and why Brotli usually compresses text tighter.
Takina · · 5 min read HTTP Caching Headers: Cache-Control and ETag Explained
Cache-Control and ETag are the two headers that control HTTP caching — how long a response stays fresh and how to revalidate it cheaply, explained.