HTTP/2 multiplexing lets you send many requests and responses at once over a single TCP connection, making web pages load way faster.
Let’s see it in action. Imagine a browser requesting a webpage.
GET /index.html HTTP/1.1
Host: example.com
This is a classic HTTP/1.1 request. The browser waits for the entire response to download before it can even start requesting other assets like CSS, JavaScript, or images. If index.html is large, or the connection is slow, everything grinds to a halt.
Now, with HTTP/2, it’s a different story. The browser initiates a single TCP connection.
GET /index.html HTTP/2
Host: example.com
But instead of waiting, it can immediately send other requests over that same connection.
GET /styles.css HTTP/2
Host: example.com
GET /script.js HTTP/2
Host: example.com
GET /logo.png HTTP/2
Host: example.com
These requests are broken down into small, independent frames. Each frame has a stream ID, allowing the server to know which request it belongs to. The server receives these frames, processes them concurrently, and sends back the responses, also as frames, tagged with their respective stream IDs.
The browser then reassembles these frames on the client side, presenting the complete webpage. This eliminates the head-of-line blocking problem inherent in HTTP/1.1, where one slow request can delay all subsequent requests on the same connection.
The core of HTTP/2 multiplexing lies in its framing layer. Unlike HTTP/1.1, which is text-based and line-oriented, HTTP/2 is binary. This binary framing allows for much more efficient parsing and transmission of data. Each frame has a fixed 9-byte header, followed by a variable-length payload. The header includes the length of the payload, the frame type (e.g., HEADERS, DATA, RST_STREAM), flags, and importantly, the stream identifier.
The stream identifier is key. It’s a 31-bit integer that uniquely identifies a bidirectional stream within the HTTP/2 connection. When a client sends a request, it initiates a new stream by sending a HEADERS frame with a new stream ID. The server can then send back response frames (HEADERS and DATA) using the same stream ID. If a request needs to be cancelled, an RST_STREAM frame is sent with the relevant stream ID.
This stream abstraction is what enables multiplexing. Multiple streams can be active concurrently on a single TCP connection. The browser and server negotiate parameters like SETTINGS_MAX_CONCURRENT_STREAMS which dictates how many streams can be active at once. A typical value might be 100, meaning up to 100 requests can be in flight simultaneously.
The server doesn’t just process requests in the order they arrive; it can prioritize them. For instance, a HEADERS frame can carry information about its priority relative to other streams, allowing the server to allocate resources more effectively. A frame with a higher priority might get processed and sent back before a lower-priority one, even if the lower-priority one arrived first. This priority is expressed as a dependency on another stream and a weight. For example, stream 5 might depend on stream 3 with a weight of 100, meaning it gets a larger share of resources when processed alongside stream 3.
The connection itself is managed by a single TCP socket. This dramatically reduces the overhead associated with establishing multiple TCP connections, which involves TCP handshakes and TLS handshakes (if using HTTPS). For each request in HTTP/1.1, there was often a new TCP connection. With HTTP/2, there’s just one. This also means fewer resources are consumed on both the client and server.
The fact that HTTP/2 is binary and uses frames means that the browser must reconstruct the original HTTP messages. It receives a stream of frames, and using the stream IDs and frame types, it pieces together the request and response headers and bodies for each individual logical request. This reconstruction is why you’ll often see browser developer tools showing individual "requests" even though they all traverse a single underlying connection.
The next challenge is understanding how this efficiency translates into security, specifically with TLS.