An asynchronous HTTP/1.1 server can handle many connections concurrently while still serializing work within each connection. Send a slow request followed by a fast request over the same persistent connection, and the fast response remains trapped behind the slow one. Send those requests over separate connections, and the fast response can arrive immediately.

That behavior is head-of-line blocking: one unit of work at the front of an ordered sequence delays independent work behind it.

HTTP/2 addresses this problem at the application layer by dividing one connection into independently identified streams. HTTP/3 goes further by running over QUIC, whose transport-level streams avoid the cross-stream blocking imposed by TCP's single ordered byte stream.

The differences are easier to understand when reduced to their scheduling and framing mechanisms. The examples below are not implementations of HTTP/2 or QUIC. They isolate the ordering constraint each protocol changes.

Reproducing the HTTP/1.1 Limitation