HTTP Protocol Versions, Recapped
What changed across HTTP 1.0/1.1, SPDY, and HTTP 2 — multiplexing, header compression, server push, and how multiplexing differs from keep-alive.
~/posts/http-versions $ cat post.md
HTTP 1 and 2
In practice today, HTTP 1.1 and HTTP 2 are what you see. 1.1 is still deployed everywhere, so worth starting with what changed from 1.0 to 1.1.
What 1.1 added
- Richer entity-based cache control — from “since timestamp” tags
like
If-Modified-SinceandExpiresto entity-shaped tags likeIf-Unmodified-Since,If-Match, andIf-None-Match. - Range requests for partial fetches of binary resources (the header
is, fittingly,
Range). - The
Hostheader — a single IP can serve multiple hosts. - Persistent connections —
Connection: keep-alive.
SPDY
Once HTTP 2 took off, SPDY became mostly historical. But since HTTP 2 inherits a lot from SPDY, it’s worth introducing.
SPDY was proposed by the Chrome team. It sits between application-layer HTTP and transport-layer TCP (OSI-wise I’d put it at the session layer, though it’s still below SSL / presentation layer). It cleanly delivered multiplexing — a capability HTTP 2 later absorbed — and gave the browser stronger caching abilities.
SPDY supports server push: when you request index.html, the server
proactively pushes bundle.js and style.css into the browser’s
SPDY cache. Follow-up requests hit the cache instead of the network.
Sidenote: the “below SSL” comment above is real — SPDY only supports HTTPS.
HTTP 2
HTTP 2 allows plain text in spec — a step up from SPDY. In practice, browsers don’t follow the spec to the letter, and the mainstream ones still only do HTTP 2 over TLS.
You get multiplexing for free in HTTP 2. There’s also header compression — SPDY had it too, but as a non-standard extension.
The mechanism is straightforward: client and server share a lookup table for common headers, and only send the index over the wire. The reason this hinged on standardization is that both sides need to agree on the table and its encoding upfront.
”Wasn’t multiplexing always a thing?”
If you ask this, you’re probably conflating multiplexing with keep-alive.
- Keep-alive: a TCP connection stays open across multiple request/response cycles.
- Multiplexing: multiple concurrent requests in flight over the same TCP connection.
They don’t conflict — they compose. For a single site:
- No keep-alive
- TCP open
- Request index.html → receive
- TCP close
- TCP open
- …
- Keep-alive
- TCP open
- Request index.html → receive
- Request bundle.js → receive
- Request style.css → receive
- …
- Multiplexing
- TCP open
- Request index.html → receive
- Concurrently request bundle.js, style.css, logo.png
- Receive them as they arrive
- …
The asset-heavy case is where multiplexing visibly wins.
Is this the same as server push?
No — server push and multiplexing aren’t the same and they don’t conflict.
Server push means: you asked for index.html, but the server figures
(barring crawlers) you’ll also ask for bundle.js and style.css,
so it pushes them too without being asked.
HTTP 2 inherits this from SPDY.