What changed from HTTP/1.1

Under HTTP/1.1, a browser or app that wanted to make six requests to the same host either opened six separate TCP connections, or queued them one after another on a small number of reused ones. Both approaches waste time — extra connections cost a TLS handshake each, and queuing means request five waits for request four to finish first.

HTTP/2 replaces this with multiplexing: a single connection carries many requests and responses at once, interleaved as numbered streams. Request five doesn't wait for request four — its frames can arrive between request four's frames on the same wire, and get reassembled on the other end. This is a genuine, measurable performance improvement, and it's why the vast majority of real-world traffic from modern apps is HTTP/2 today, not HTTP/1.1.

Why that makes traffic harder to read raw

If you tried to read an HTTP/2 connection as raw bytes off the wire, you wouldn't see six clean requests — you'd see interleaved binary frames from all of them at once, in an order that has nothing to do with when each request logically started or finished. A tool that only understands HTTP/1.1-style request/response pairs either can't parse this at all, or flattens it into something that loses the fact that these requests were genuinely concurrent.

A proxy tool built for HTTP/2 has to actually implement stream demultiplexing — tracking each stream's frames independently and reassembling them into a coherent request and response — rather than treating the connection as one linear conversation. Flow control adds another layer: HTTP/2 limits how much unacknowledged data can be in flight per stream and per connection, so a tool has to track window sizes correctly or it'll stall on connections that have several large responses in flight simultaneously.

What this means for debugging

In practice, this is invisible when it's done right — you should be able to look at a capture and see individual requests exactly the way you would with HTTP/1.1, one row each, correct headers and body, correct timing. The complexity is entirely in getting there. If a proxy tool shows HTTP/2 traffic as garbled, merged, or missing entirely, that's usually a sign it's not actually implementing the protocol, just tolerating it.

The other thing worth knowing: HTTP/2 is negotiated automatically during the TLS handshake (via ALPN), not something an app opts into explicitly. So if you're debugging an app and wondering why its traffic "looks different" from an older capture, checking whether the connection upgraded from HTTP/1.1 to HTTP/2 is often the explanation — not a change in the app's own code at all.