---
topic: web-performance
author: Crashtech Editorial
published: Nov 14, 2026 · read: 4 min
---

HTTP/1.1, HTTP/2 and HTTP/3: What Each Version Fixed and What It Left Broken

Persistent connections, multiplexing, header compression and QUIC: each HTTP version removed one bottleneck and exposed the next. How to choose and verify.

– –

A request for /index.html means the same thing it meant in the nineties. What changed is the cost of asking for forty things at once, and each version of HTTP is the answer to the bottleneck the last one left behind.

Timeline

VersionYearHeadline change
HTTP/1.01996One request per connection, headers introduced
HTTP/1.11997Persistent connections, chunked transfer, host header
HTTP/22015Binary framing, multiplexing, header compression
HTTP/32019 (standardised 2022)QUIC over UDP, independent streams

HTTP/1.1: text, one at a time

HTTP/1.1 keeps a TCP connection open for several requests (persistent connections), which saved the cost of a fresh handshake for each file. But on one connection, responses come back in order. A slow response blocks the ones behind it. This is HTTP-level head-of-line blocking.

Pipelining was meant to help (send several requests without waiting), but servers and proxies handled it unreliably, so browsers disabled it. The workaround was brute force: open six or so connections per host and spread requests across them, with tricks like domain sharding and bundling files together.

Workarounds that HTTP/2 makes harmful

Domain sharding, sprite sheets and giant bundles were HTTP/1.1 optimisations. Under HTTP/2 they cost you: sharding splits the single multiplexed connection, and bundling defeats caching of individual files.

HTTP/2: many streams, one connection

Binary framing easier to parse
Messages are split into frames tagged with a stream id, instead of newline-delimited text.
Multiplexing no more request queue
Many requests and responses interleave on one connection. A slow response no longer blocks fast ones at the HTTP level.
HPACK header compression less repeated data
Headers like cookies and user-agent repeat on every request. HPACK keeps a table so repeats cost a few bytes.
Stream priority and push mixed results
Priorities let clients hint at importance. Server push was meant to send resources early, but proved hard to use well, and major browsers have since dropped it.

What HTTP/2 left broken

HTTP/2 still rides on one TCP connection. TCP delivers bytes strictly in order, so when a single packet is lost, TCP holds back everything after it, including data belonging to other, unaffected streams, until the retransmission arrives. On a clean wired network that is rare. On lossy mobile or Wi-Fi it can make HTTP/2 worse than several HTTP/1.1 connections.

HTTP/3: a new transport underneath

HTTP/3 keeps HTTP/2’s ideas (streams, header compression via QPACK) but runs over QUIC, a transport built on UDP.

HTTP/1.1  : HTTP  / TLS / TCP
HTTP/2    : HTTP  / TLS / TCP
HTTP/3    : HTTP  / QUIC (streams + TLS 1.3 + loss recovery) / UDP

UDP is only the carrier. QUIC implements reliability, congestion control and encryption itself, in user space. That unlocks:

FeatureWhy it matters
Independent streamsA lost packet only delays the stream it belongs to, ending transport-level head-of-line blocking
Faster connection setupTransport and TLS 1.3 handshakes combine, and repeat visits can send data on the first flight (0-RTT, with replay caveats)
Connection migrationA connection id survives a change of IP address, so a phone moving from Wi-Fi to cellular keeps its connection
Always encryptedTLS 1.3 is part of QUIC, with most of the transport header protected
Easier evolutionImplemented in libraries, not in operating-system kernels and middleboxes
Advertisement

Side by side

HTTP/1.1HTTP/2HTTP/3
TransportTCPTCPQUIC over UDP
MultiplexingNo (several connections)Yes, streamsYes, independent streams
Header compressionNoneHPACKQPACK
Head-of-line blockingHTTP levelTCP levelLargely removed
EncryptionOptionalPractically required by browsersMandatory
Setup costTCP + TLS handshakesTCP + TLS handshakesCombined, fewer round trips

Choosing and verifying

HTTP/3 is not automatically faster for every user. Gains are largest on high-latency, lossy or mobile networks. On a fast, stable connection, HTTP/2 and HTTP/3 are close. Some corporate networks block or throttle UDP, so clients must fall back to HTTP/2, and good deployments keep both enabled.

Servers advertise HTTP/3 with an Alt-Svc header, and browsers switch on later requests, which is why the first visit often shows h2.

curl -sI --http2 https://example.com | head -1     # HTTP/2 200
curl -sI --http3 https://example.com | head -1     # needs a curl built with HTTP/3
curl -sI https://example.com | grep -i alt-svc     # alt-svc: h3=":443"

In browser developer tools, add the Protocol column in the Network panel and look for h2 or h3.

Do

Enable HTTP/2 everywhere, add HTTP/3 behind your CDN or proxy with HTTP/2 fallback, drop HTTP/1.1-era sharding, keep files cacheable individually, and measure real users on slow networks before and after.

Don't

Assume a version number is a performance guarantee. A slow backend, a huge uncompressed payload or a render-blocking script costs more than any protocol difference.

Takeaway

Each HTTP version removed the bottleneck of the one before: HTTP/1.1 reused connections, HTTP/2 multiplexed requests on one connection, HTTP/3 stopped one lost packet from stalling everything by moving to QUIC. Enable all three with fallbacks, retire the old workarounds, and test on the networks your users really have.

Advertisement

Frequently asked questions

What problem does HTTP/2 solve compared with HTTP/1.1?

HTTP/1.1 handles one request at a time per connection, so browsers open several connections and still queue requests. HTTP/2 multiplexes many requests as interleaved streams over a single connection, compresses repeated headers with HPACK and allows stream prioritisation, cutting connection overhead and latency.

What is head-of-line blocking and does HTTP/2 remove it?

It is when one delayed item holds up everything behind it. HTTP/2 removes it at the HTTP level, but all streams share one TCP connection, so a single lost packet stalls every stream until retransmitted. HTTP/3 moves to QUIC, where streams are independent, to remove it at the transport level.

Why does HTTP/3 use UDP?

QUIC runs over UDP so it can implement its own reliable, encrypted, multiplexed streams in user space instead of waiting on operating-system TCP changes. UDP is just the delivery vehicle. QUIC adds reliability, congestion control and TLS 1.3 on top, and supports faster connection setup and connection migration.

How can I check which HTTP version a site is using?

Use curl with the --http2 or --http3 flags and read the response line, or open browser developer tools, add the Protocol column to the network panel and read h2 or h3. Servers advertise HTTP/3 through the Alt-Svc header, so first visits often still use HTTP/2.

Sources & further reading

/* Comments */