Understanding HTTP/3: the transport most of the web is moving to
If you spend any time debugging the network, you've seen h3 appear in cipher-suite lists and connection logs over the last few years. HTTP/3 is no longer experimental — a meaningful share of the web is served over it now. This post explains what it actually is, in the plainest terms I can manage.
Three acronyms, one idea
HTTP/3 is the application layer. The thing that carries it is QUIC, which is a transport protocol implemented on top of UDP. Saying "HTTP/3 over QUIC" is like saying "Git over SSH" — the two layers swap their interaction but the idea of the top layer stays familiar.
The headline change: instead of one byte stream per connection, QUIC gives you multiple independent byte streams on a single connection, and congestion control per connection rather than per stream.
What the 0-RTT fuss is about
Classic TLS 1.3 resumes a session in one round trip. QUIC, with session resumption, can start sending application data together with that first flight — zero additional round trips. It's a real win for clients that reconnect often, which is most of them.
The trade-off, worth stating plainly: 0-RTT data can be replayed. Servers that accept early data are expected to treat it as idempotent or validate it, because the client's first packet may have been captured and resent.
No more head-of-line blocking
On TCP + TLS, one lost segment blocks every stream sharing that connection until the missing piece is retransmitted. QUIC's independent streams mean a drop in the video stream doesn't stall the chat stream running alongside it. For multiplexed traffic this is the difference between a hiccup and a freeze.
Because QUIC avoids the TCP handshake, runs on UDP, and moves retransmission and reordering into the QUIC layer itself, it also travels surprisingly cleanly through NATs and load balancers.
One practical caveat from the field: middleboxes and tunnels that drop or rate-limit UDP still break QUIC. If you proxy traffic, test both UDP and TCP paths. Many "suddenly slower" reports I've seen turned out to be a UDP policy on some equipment in the middle.
What to check when something feels off
Three quick probes worth having in your toolbox:
# does the server advertize h3 at all?
curl -sI https://example.com --http3 2>&1 | grep -i '^HTTP'
# what does the client negotiate?
openssl s_client -connect example.com:443 -alpn h2,h3 -servername example.com 2>&1 | grep ALPN
If the server supports QUIC but your path doesn't deliver UDP, the negotiation silently falls back to HTTP/2. Graceful fallback is the point — but it also means "it worked, just slower" can hide a broken UDP path for years.
Is this where it ends?
Probably not, and that's fine. The transport has been stable long enough to be boring, which is exactly the quality you want from the layer underneath your content. Boring transports make for honest debugging.