JA EN
LearnNetworking
·★ MEMBER·8 min read

HTTP/1.1 → 2 → 3 — The Road to Multiplexing

Thirty years of HTTP is really one argument: how many conversations can share a single connection? Why 1.1's one-at-a-time rule created traffic jams, what HTTP/2 solved with frames and streams, why the jam simply moved one floor down, what HTTP/3 separated by swapping the foundation — and how to measure your own network before picking one.

ModalitytextTasksystems

One question, one answer — and a traffic jam

HTTP is a startlingly simple bargain. Send a request, get a response. That alone carried it for thirty years. But one condition comes attached: on a single connection, you cannot begin the next response until the current one has finished.

Picture a government office with exactly one counter. Nobody is called until the person ahead of you is done, so ten errands mean queuing ten times.

HTTP/1.0 queued up literally that way — open a connection per request, close it when the response arrives. HTTP/1.1 made connections reusable with keep-alive and added the Host header and chunked transfer. Real improvements, but the one question, one answer condition survived intact.

There was an escape hatch: pipelining, which lets you send the next request without waiting for the previous response. The catch is that responses must come back in the order they were requested. If the first request is a slow API and the second is a small image, the image cannot ship even though it is sitting ready. The front of the line stalls everything behind it — that is head-of-line blocking (HOL blocking). Too many sites broke on middleboxes that implemented it inconsistently, and major browsers ended up disabling it by default.

The brute-force fix browsers found, and its bill

If one connection is not enough, open more. Browsers settled on roughly six parallel connections per origin. The time it takes looks about like this.

TRTT×NcT \approx \mathrm{RTT} \times \left\lceil \frac{N}{c} \right\rceil
(1)

NN is the number of assets to fetch, cc the number of connections you can hold open, and RTT\mathrm{RTT} the time for one round trip. In plain words: more assets means proportionally more time. Once a single page routinely carried a hundred images and scripts, that was fatal.

So the industry attacked NN: CSS sprites gluing small images into one sheet, JS and CSS bundles, data URIs inlined straight into the HTML. The brute-force move on cc was domain sharding — scatter static assets across img1 and img2 to buy six connections per hostname.

But connections are not free. Each one pays for a TCP handshake and a TLS handshake, and its congestion window (the running estimate of how much may be in flight at once) starts from scratch. Open six and all six begin in the "still slow" state — and then they compete with each other for the same bandwidth.

FIG 1Read the x-axis n as "number of assets on the page" and the y-axis as "round trips before the page is up." The O(n) line is HTTP/1.1 — every extra asset is another turn in the queue. The flat O(1) line is what multiplexing buys: the same number of round trips no matter how many assets there are. Switch the y-axis to linear and you can see this is a difference in orders of magnitude, not a few percent

HTTP/2 — carving several streams inside one pipe

HTTP/2, standardized in 2015 and now specified by RFC 9113, rebuilt the picture around three units. A frame is the smallest unit on the wire: a small block carrying a type, a length, and the ID of the stream it belongs to. A stream is a numbered virtual channel for one exchange (one request paired with one response). A connection is a single TCP connection, and hundreds of streams live inside it.

The decisive part is that every frame carries a stream ID. You may interleave another stream's data before finishing the current response, because the receiver just sorts by ID. The ordering constraint evaporates, and what took six connections now fits in one. Trading newline-delimited text for a binary frame format is what makes that sorting cheap and unambiguous for a machine.

The other pillar is header compression. Headers run from a few hundred bytes to several KB once cookies are involved, so fetching a hundred assets means sending nearly identical headers a hundred times. HPACK (RFC 7541) attacks this three ways: a static table numbering 61 common header entries, a dynamic table that bot

What's behind this

§

Members-only from here

371 walkthroughs, 26 textbook chapters, 48 student units and 6 close readings — all included for $4.99/mo, with three new explainers every day. Cancel any time; access runs to the end of the period.

Already a member? Sign in to keep reading

Comments

Sign in to comment