HTTP/1.1, HTTP/2 and HTTP/3: What Changed and Why

October 8, 2026 · 3 min read

A GET /index.html means the same thing in every version of HTTP: the method, path, headers and status codes from HTTP requests and responses are unchanged. What changed is how those requests are packed onto the network — and each version fixed the biggest bottleneck of the one before.

HTTP/1.1: one at a time

HTTP/1.1 sends requests as plain text, and each connection handles one request at a time: send a request, wait for the whole response, then send the next.

A modern page needs dozens of files. To avoid waiting for them one by one, browsers open up to six connections per domain, each with its own TCP and TLS handshake. Developers worked around the limit with hacks: bundling everything into one huge file, image sprites, and spreading assets across several domains.

HTTP/2: many streams, one connection

HTTP/2 (2015) changed the wire format to binary frames and added multiplexing: many requests and responses share one connection at the same time, each as its own numbered stream, their frames interleaved.

  • One connection per origin instead of six — one handshake.
  • No waiting for one response before asking for the next.
  • Header compression (HPACK) — repeated headers like cookies and user-agent aren't resent in full on every request.

Most of the old hacks became unnecessary, or even harmful.

The wall HTTP/2 hit: TCP

HTTP/2 multiplexes streams, but it runs over TCP, and TCP promises one thing: a single, ordered stream of bytes. If one packet is lost, TCP holds back everything after it until the missing packet is retransmitted — even data belonging to other streams that arrived perfectly well.

HTTP/2 over TCP — one ordered stream
html 1
pending
css 1
pending
js 1
pending
html 2
pending
css 2
pending
js 2
pending
HTTP/3 over QUIC — each stream ordered on its own
html 1
pending
css 1
pending
js 1
pending
html 2
pending
css 2
pending
js 2
pending

Three files — HTML, CSS, JS — are downloading at once over one connection, their packets interleaved. Both HTTP/2 and HTTP/3 multiplex streams like this. The difference is what happens when one packet is lost.

0 / 3

That's head-of-line blocking at the transport layer. On a good connection it rarely matters. On a lossy mobile network, one lost packet stalls every file on the page, and it happens again and again.

HTTP/3: QUIC instead of TCP

HTTP/3 keeps HTTP/2's ideas but runs over QUIC, a transport protocol built on UDP. QUIC handles reliability and ordering per stream: a lost packet delays only the stream it belongs to.

QUIC brings other improvements too:

  • Faster setup. QUIC combines the transport and TLS 1.3 handshakes, so a new connection is ready in one round trip instead of two or three, and a returning visitor can often send data immediately (0-RTT).
  • Connection migration. A connection is identified by an ID, not by IP address and port, so it survives switching from Wi-Fi to mobile data without starting over.
  • Encryption is mandatory — there's no unencrypted HTTP/3.

Side by side

HTTP/1.1HTTP/2HTTP/3
TransportTCPTCPQUIC over UDP
FormatTextBinary framesBinary frames
Requests per connection at onceOneMany (multiplexed)Many (multiplexed)
Head-of-line blockingPer connectionAt the TCP levelOnly within one stream
New connection setupTCP + TLS handshakesTCP + TLS handshakesOne combined handshake

What it means for you

  • You rarely choose. Browsers and servers negotiate the version automatically. Most CDNs and modern servers support HTTP/2 and HTTP/3 with a setting; browsers discover HTTP/3 through an Alt-Svc header or DNS records and switch over.
  • Drop the HTTP/1.1 hacks. Splitting assets across many domains now costs extra connections; giant all-in-one bundles defeat caching. Many reasonably sized files are fine.
  • The biggest wins are on poor networks — mobile users and lossy connections — which are exactly the users with the slowest experience today.

In one sentence

HTTP/2 let many requests share one connection; HTTP/3 moved that connection onto QUIC, so a single lost packet no longer holds up everything else.