9 min
  • HTTP
  • TCP/IP

HTTP/1.1, HTTP/2, HTTP/3

Everything in this track so far — methods, status codes, fields, caching, cookies — is identical across all three versions. That is not a coincidence; it is how the specifications are organised. RFC 9110 defines HTTP's semantics once, and RFC 9112, 9113 and 9114 each define a different way to put those semantics on a wire.

So the version number is a statement about frame format and multiplexing, and about nothing else.

Loading the HTTP Explorer simulation…

Two different queues, fixed one at a time

HTTP/1.1 sends one request at a time per connection. Browsers work around that by opening about six connections per host, which turns twenty-four resources into four rounds of queueing. That is application-layer

head-of-line blocking, and HTTP/2 removes it completely: requests become numbered streams interleaved over one connection, all in flight at once.

What HTTP/2 could not remove is the queue underneath. TCP delivers bytes in order and has no idea the multiplexing exists, so one lost segment stalls every stream sharing the connection — which is worse than HTTP/1.1, where a loss stalls one of six.

VersionRequests in flightApp-layer HOLTransport HOL
HTTP/1.1~6, one per connYesPer connection
HTTP/2Many, one connNoYes, across all streams
HTTP/3Many, one connNoNo
Check yourself
In what situation is HTTP/2 measurably worse than HTTP/1.1?

Why HTTP/3 had to leave TCP

The transport queue cannot be fixed inside HTTP, because the ordering guarantee belongs to TCP and TCP cannot be told about streams. So QUIC replaces it: a transport built on UDP that tracks loss per stream, so a gap in one stream delivers nothing but that stream.

QUIC folds the TLS handshake into its own, which is the other saving — an HTTP/3 connection is usable a full round trip before an HTTP/1.1 or HTTP/2 one over TLS.

The compression story is the same idea twice. HPACK in HTTP/2 and QPACK in HTTP/3 keep a shared table of previously-seen header fields, so repeated fields are sent as a small index. The saving starts on the second request, not the first.

Predict what happens next
HTTP/3 runs over UDP. Does that make it unreliable?

Key takeaways

  • HTTP’s semantics are defined once, in RFC 9110. A version number describes framing and multiplexing and nothing else.
  • HTTP/1.1 queues requests behind about six connections per host; HTTP/2 removes that queue entirely.
  • HTTP/2 inherits TCP’s in-order delivery, so a single loss stalls every stream — worse than HTTP/1.1 on a lossy link.
  • HTTP/3 escapes it by replacing TCP with QUIC, which tracks loss per stream and folds in the TLS handshake.
  • HPACK and QPACK compress headers against a shared table, so the saving begins on the second request rather than the first.

Take it further