Module 13 · Application protocols · Lesson 2 of 4
HTTP/1.1, HTTP/2 and HTTP/3
Three versions of the same semantics with very different wire behaviour: HTTP/1.1's one request per connection at a time, HTTP/2's multiplexed binary streams over one TCP connection, and HTTP/3's streams over QUIC. What each fixed.
Why it matters
Every API call and page load you design rides on one of these versions, and the differences show up as real latency: how many connections a client opens, what happens when one packet is lost, how many round trips a cold request costs on a phone. Choosing protocols for a gateway, a CDN, a gRPC service or a mobile client means knowing what each version actually does on the wire.
The idea
All three versions share HTTP's semantics: methods, status codes, headers, caching rules, URLs. What changes is the framing (how messages are laid out in bytes) and the transport underneath. Each version was designed to remove the main performance problem of the one before.
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Year | 1997 (refined 2014, 2022) | 2015 | 2022 |
| Format | Text | Binary frames | Binary frames |
| Transport | TCP (+ TLS) | TCP + TLS | QUIC over UDP (TLS 1.3 built in) |
| Requests per connection | One at a time (pipelining exists but is unusable in practice) | Many concurrent streams | Many concurrent streams |
| Header compression | None | HPACK | QPACK |
| Head-of-line blocking | Per connection: a slow response blocks the next | Fixed at HTTP level; still at TCP level on loss | Gone: loss stalls only the affected stream |
| Cold-start round trips (with TLS) | 2–3 | 2–3 | 1, or 0 on resumption |
HTTP/1.1
A connection carries one request and its response at a time. Keep-alive lets the connection be reused for the next request, but a slow response blocks everything queued behind it. Browsers therefore opened about six connections per host, and sites invented workarounds: domain sharding to get more connections, concatenating scripts and images into bundles and sprites to make fewer requests. Headers are repeated as plain text on every request, often kilobytes of cookies. Its strengths are simplicity, readability and universal support; it is still common between services and behind load balancers.
HTTP/2
One TCP connection carries many streams in parallel; requests and responses are split into binary frames that interleave, so a slow response no longer blocks others at the HTTP level. Headers are compressed with HPACK, which remembers previously sent headers. Streams have weights and flow control. Domain sharding and bundling become unnecessary or harmful. gRPC is built on HTTP/2 for its multiplexing and streaming. The weakness is underneath: all streams share one TCP byte stream, so a single lost packet stalls every stream until it is retransmitted (TCP head-of-line blocking), which on lossy mobile networks can make HTTP/2 slower than several HTTP/1.1 connections. Server push, meant to send resources before they are asked for, was rarely beneficial and has been removed from major browsers.
HTTP/3 and QUIC
QUIC is a transport built on UDP that provides reliable, independently ordered streams, congestion control, and TLS 1.3 encryption as one integrated layer in user space. HTTP/3 maps HTTP onto it. Benefits: no transport head-of-line blocking across streams; a combined transport and crypto handshake in one round trip, and zero round trips when resuming with a known server (for idempotent requests, because 0-RTT data can be replayed); connection migration, so a phone switching from Wi-Fi to cellular keeps its connection because QUIC identifies connections by ID rather than by IP and port; and faster evolution, since it lives in applications rather than kernels and middleboxes cannot meddle with its encrypted headers. Costs: more CPU per byte than kernel TCP today, UDP being blocked or throttled on some networks (clients fall back to HTTP/2), and less mature tooling.
Negotiation and coexistence
Clients and servers agree on HTTP/2 during the TLS handshake using ALPN. HTTP/3 is discovered through an Alt-Svc header or DNS HTTPS records, and clients race it against TCP. Most deployments terminate HTTP/2 and HTTP/3 at the edge (CDN, load balancer) and speak HTTP/1.1 or HTTP/2 to backends inside the data centre, where loss is rare and latency tiny.
Trade-offs
HTTP/1.1 is simple and debuggable and wastes connections and bytes. HTTP/2 multiplexes efficiently and compresses headers, and concentrates all risk on one TCP connection. HTTP/3 removes transport head-of-line blocking and handshake latency and survives network changes, and costs CPU, UDP compatibility and operational familiarity. The edge benefits most from newer versions; inside a data centre the difference is small.
In an interview
Choose by link quality and client: "Mobile clients talk HTTP/3 to the CDN, which matters on lossy cellular links and network switches, with fallback to HTTP/2. Between the edge and services we use HTTP/2, and gRPC internally for multiplexed streaming. We stopped bundling everything into one file once HTTP/2 made many small requests cheap."
Check yourself
A mobile app moved from HTTP/1.1 (six connections) to HTTP/2 (one connection) and got faster on Wi-Fi but slower on a lossy cellular network. Why, and what helps?