HTTP/2 and HTTP/3

HTTP & the web · Advanced · 14 min

Protocol versions change which performance tricks help or hurt, from domain sharding to bundling.

HTTP/1.1 sends one request at a time per connection; a slow response blocks the ones behind it (head-of-line blocking). Browsers work around this by opening about six connections per origin, and developers used to bundle files, sprite images and shard domains.

HTTP/2 (2015) keeps the same semantics but changes the framing:

  • Binary frames and streams: many requests and responses are multiplexed over a single TCP connection, interleaved, so one slow response doesn't block the others at the HTTP level.
  • HPACK header compression, which matters because headers (cookies, user agents) repeat on every request.
  • Prioritisation hints, later simplified by the Priority header (RFC 9218).
  • In browsers it requires TLS; the version is negotiated in the TLS handshake via ALPN (h2).

But TCP itself still delivers bytes in order: one lost packet stalls all streams until it's retransmitted, which hurts on lossy mobile networks.

HTTP/3 (2022) runs over QUIC, a transport built on UDP:

  • Streams are independent at the transport level, so packet loss only stalls the affected stream.
  • TLS 1.3 is built in, combining transport and crypto handshakes into one round trip, and resumed connections can send data in 0-RTT.
  • Connection migration: a connection survives a switch from Wi-Fi to cellular because it's identified by a connection ID, not the IP/port tuple.

Servers advertise HTTP/3 with the Alt-Svc response header or the DNS HTTPS record; browsers then switch. For developers: serve over HTTP/2 or 3, stop domain sharding, and bundle only as much as makes sense for caching.

Example

# Which protocol does a site negotiate?
$ curl -sI --http2 https://www.cloudflare.com -o /dev/null -w "%{http_version}\n"
2

# Does it advertise HTTP/3?
$ curl -sI https://www.cloudflare.com | grep -i alt-svc
alt-svc: h3=":443"; ma=86400

# Try HTTP/3 directly (curl built with HTTP/3 support)
$ curl -sI --http3-only https://www.cloudflare.com -o /dev/null -w "%{http_version}\n"
3

# In browser devtools: Network tab, right-click columns, enable "Protocol" (h2, h3)

Remember

  • HTTP/2 multiplexes many streams over one TCP connection
  • TCP packet loss still blocks all HTTP/2 streams
  • HTTP/3 uses QUIC over UDP: independent streams, built-in TLS 1.3, connection migration
  • Alt-Svc or DNS HTTPS records advertise HTTP/3

Watch out for

  • Keeping HTTP/1-era domain sharding, which defeats HTTP/2 multiplexing and adds handshakes.

Check yourself

  1. What problem does HTTP/3 solve that HTTP/2 cannot?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Evolution_of_HTTP