HTTP/1.1 vs HTTP/2
HTTP/2 was standardized in 2015 (RFC 7540, superseded by RFC 9113) to solve the performance problems of HTTP/1.1: head-of-line blocking from sequential request handling, large uncompressed headers repeated on every request, and the 6-connections-per-domain workaround. HTTP/2 changes the wire format completely while keeping HTTP semantics intact – the same methods, headers, and status codes work identically.
HTTP/1.1 is a text-based protocol with persistent connections. Browsers open up to 6 parallel connections per origin to work around sequential request-response ordering. HTTP/2 is a binary protocol that multiplexes all requests over a single TCP connection and compresses headers with HPACK (85–90% reduction). For workloads dominated by many small assets, HTTP/2 significantly reduces round-trip overhead. The semantics – methods, headers, status codes – are identical. Only the wire format changed.
| Feature | HTTP/1.1 | HTTP/2 |
|---|---|---|
| Wire format | Text-based (ASCII, CRLF) | Binary framing (length-prefixed frames) |
| Multiplexing | No true multiplexing – responses are ordered. HTTP/1.1 defines pipelining but it was poorly deployed. Browsers open up to 6 parallel TCP connections per origin as a workaround. | Full – multiple streams over one TCP connection, independent request-response ordering |
| HOL blocking | Severe – slow response blocks all subsequent ones | Reduced (HTTP layer) – TCP HOL blocking remains |
| Header compression | None – headers repeated in full every request | HPACK – 85–90% header size reduction via shared table |
| Server push | Not supported | Supported (rarely effective; Chrome removed it 2022) |
| Stream prioritization | Not supported | Supported – weights and dependencies per stream |
| TLS requirement | Optional (plain HTTP/1.1 works) | Required in practice (browsers enforce TLS for HTTP/2) |
| Connections per origin | 6 (browser limit – domain sharding workaround) | 1 – multiplexing makes sharding unnecessary |
| Debugging | Human readable – telnet/netcat works | Binary – requires dedicated tools (Wireshark, nghttp2) |
| Performance on packet loss | Predictable – 6 connections, loss affects 1 | Can be worse – all streams blocked by single TCP loss |
| RFC | RFC 9110 / RFC 9112 | RFC 9113 |
When to use HTTP/1.1
HTTP/1.1 applies only to legacy systems that cannot be upgraded, internal tools where HTTP/2 support isn't available, or debugging scenarios where human-readable text is required. For any new deployment, HTTP/2 is strictly preferable.
When to use HTTP/2
HTTP/2 is the default for all modern HTTPS deployments – Nginx, Apache, Caddy, and every CDN negotiate it via ALPN. It delivers the most benefit for pages loading many small resources (APIs, JS bundles, CSS, fonts, images). If TLS is already in use, enabling HTTP/2 is essentially free.
Common Mistakes
- Domain sharding with HTTP/2 – splitting assets across cdn1.example.com, cdn2.example.com hurts performance by forcing additional TCP connections and TLS handshakes instead of using HTTP/2 multiplexing.
- Combining HTTP/1.1 optimizations (file concatenation, inlining) with HTTP/2 – these optimizations reduce multiplexing effectiveness and make cache invalidation worse.
- Assuming HTTP/2 eliminates all HOL blocking – it eliminates HTTP-layer blocking, but TCP-level HOL blocking remains. HTTP/3 (QUIC) solves this.
- Enabling HTTP/2 server push aggressively – Chrome removed support in v106 (2022). Misuse causes wasted bandwidth by pushing resources the client already has cached.
FAQ
Does HTTP/2 require HTTPS?
Not in the RFC, but yes in practice. All major browsers only implement HTTP/2 over TLS using ALPN negotiation. An HTTP/2 server that supports cleartext (h2c) will only work with non-browser clients.
What replaced HTTP/2 server push?
The 103 Early Hints status code and the Link header with rel=preload are the recommended alternatives. They tell the browser to start fetching resources while the server processes the main request, without the reliability issues of push.
Should I use HTTP/2 or HTTP/3?
HTTP/3 (QUIC) solves TCP head-of-line blocking, which matters on lossy networks (mobile, satellite). HTTP/2 is more universally supported and firewall-friendly. Modern CDNs support both and negotiate automatically.