HTTP/1.1, HTTP/2 and HTTP/3: What Each Version Fixed and What It Left Broken
Persistent connections, multiplexing, header compression and QUIC: each HTTP version removed one bottleneck and exposed the next. How to choose and verify.
On this page
A request for /index.html means the same thing it meant in the nineties. What changed is the cost of asking for forty things at once, and each version of HTTP is the answer to the bottleneck the last one left behind.
Timeline
| Version | Year | Headline change |
|---|---|---|
| HTTP/1.0 | 1996 | One request per connection, headers introduced |
| HTTP/1.1 | 1997 | Persistent connections, chunked transfer, host header |
| HTTP/2 | 2015 | Binary framing, multiplexing, header compression |
| HTTP/3 | 2019 (standardised 2022) | QUIC over UDP, independent streams |
HTTP/1.1: text, one at a time
HTTP/1.1 keeps a TCP connection open for several requests (persistent connections), which saved the cost of a fresh handshake for each file. But on one connection, responses come back in order. A slow response blocks the ones behind it. This is HTTP-level head-of-line blocking.
Pipelining was meant to help (send several requests without waiting), but servers and proxies handled it unreliably, so browsers disabled it. The workaround was brute force: open six or so connections per host and spread requests across them, with tricks like domain sharding and bundling files together.
Domain sharding, sprite sheets and giant bundles were HTTP/1.1 optimisations. Under HTTP/2 they cost you: sharding splits the single multiplexed connection, and bundling defeats caching of individual files.
HTTP/2: many streams, one connection
What HTTP/2 left broken
HTTP/2 still rides on one TCP connection. TCP delivers bytes strictly in order, so when a single packet is lost, TCP holds back everything after it, including data belonging to other, unaffected streams, until the retransmission arrives. On a clean wired network that is rare. On lossy mobile or Wi-Fi it can make HTTP/2 worse than several HTTP/1.1 connections.
HTTP/3: a new transport underneath
HTTP/3 keeps HTTP/2’s ideas (streams, header compression via QPACK) but runs over QUIC, a transport built on UDP.
HTTP/1.1 : HTTP / TLS / TCP
HTTP/2 : HTTP / TLS / TCP
HTTP/3 : HTTP / QUIC (streams + TLS 1.3 + loss recovery) / UDP
UDP is only the carrier. QUIC implements reliability, congestion control and encryption itself, in user space. That unlocks:
| Feature | Why it matters |
|---|---|
| Independent streams | A lost packet only delays the stream it belongs to, ending transport-level head-of-line blocking |
| Faster connection setup | Transport and TLS 1.3 handshakes combine, and repeat visits can send data on the first flight (0-RTT, with replay caveats) |
| Connection migration | A connection id survives a change of IP address, so a phone moving from Wi-Fi to cellular keeps its connection |
| Always encrypted | TLS 1.3 is part of QUIC, with most of the transport header protected |
| Easier evolution | Implemented in libraries, not in operating-system kernels and middleboxes |
Side by side
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Transport | TCP | TCP | QUIC over UDP |
| Multiplexing | No (several connections) | Yes, streams | Yes, independent streams |
| Header compression | None | HPACK | QPACK |
| Head-of-line blocking | HTTP level | TCP level | Largely removed |
| Encryption | Optional | Practically required by browsers | Mandatory |
| Setup cost | TCP + TLS handshakes | TCP + TLS handshakes | Combined, fewer round trips |
Choosing and verifying
HTTP/3 is not automatically faster for every user. Gains are largest on high-latency, lossy or mobile networks. On a fast, stable connection, HTTP/2 and HTTP/3 are close. Some corporate networks block or throttle UDP, so clients must fall back to HTTP/2, and good deployments keep both enabled.
Servers advertise HTTP/3 with an Alt-Svc header, and browsers switch on later requests, which is why the first visit often shows h2.
curl -sI --http2 https://example.com | head -1 # HTTP/2 200
curl -sI --http3 https://example.com | head -1 # needs a curl built with HTTP/3
curl -sI https://example.com | grep -i alt-svc # alt-svc: h3=":443"
In browser developer tools, add the Protocol column in the Network panel and look for h2 or h3.
Do
Enable HTTP/2 everywhere, add HTTP/3 behind your CDN or proxy with HTTP/2 fallback, drop HTTP/1.1-era sharding, keep files cacheable individually, and measure real users on slow networks before and after.
Don't
Assume a version number is a performance guarantee. A slow backend, a huge uncompressed payload or a render-blocking script costs more than any protocol difference.
Takeaway
Each HTTP version removed the bottleneck of the one before: HTTP/1.1 reused connections, HTTP/2 multiplexed requests on one connection, HTTP/3 stopped one lost packet from stalling everything by moving to QUIC. Enable all three with fallbacks, retire the old workarounds, and test on the networks your users really have.
Frequently asked questions
What problem does HTTP/2 solve compared with HTTP/1.1?
HTTP/1.1 handles one request at a time per connection, so browsers open several connections and still queue requests. HTTP/2 multiplexes many requests as interleaved streams over a single connection, compresses repeated headers with HPACK and allows stream prioritisation, cutting connection overhead and latency.
What is head-of-line blocking and does HTTP/2 remove it?
It is when one delayed item holds up everything behind it. HTTP/2 removes it at the HTTP level, but all streams share one TCP connection, so a single lost packet stalls every stream until retransmitted. HTTP/3 moves to QUIC, where streams are independent, to remove it at the transport level.
Why does HTTP/3 use UDP?
QUIC runs over UDP so it can implement its own reliable, encrypted, multiplexed streams in user space instead of waiting on operating-system TCP changes. UDP is just the delivery vehicle. QUIC adds reliability, congestion control and TLS 1.3 on top, and supports faster connection setup and connection migration.
How can I check which HTTP version a site is using?
Use curl with the --http2 or --http3 flags and read the response line, or open browser developer tools, add the Protocol column to the network panel and read h2 or h3. Servers advertise HTTP/3 through the Alt-Svc header, so first visits often still use HTTP/2.
/* Comments */
Comments are offline right now — we reconnect automatically, nothing is lost.