HTTP/2 Exploration – Part 1: Multiplexing

One of the main features of Gatling 3 is the HTTP/2 support. Its implementation is one of the main reasons of the rewriting of a specific HTTP client for Gatling. If you want to know more about this new HTTP client, you can read our latest article, written by Stéphane Landelle here.

HTTP/2, as its name suggests, is the second version of the HTTP protocol. The previous version was HTTP/1.1, which was initially released on 1997.

In this article and the following ones, we are going to see what is HTTP/2 and explain the new features coming with this protocol.

Multiplexing in HTTP

What is multiplexing and why do we want it?

Multiplexing: to be able to send different signals (here requests) on the same communication link.

A limitation of the HTTP/1 protocol, is that each HTTP connection is only able to handle one request at a time. It means that the only way to parallelize multiple requests is to open several HTTP connections. That is what browsers do. They open multiple connections (6 by remote for most of them), to be able to launch potentially 6 requests at a time to a given remote.

It is not very resource and network efficient. Opening more connections is an overhead for both the client and the server. TLS handshakes must be performed for each connection if you are doing HTTPS, the TCP slow start process must be performed etc.

And what happened if you want to perform more than 6 requests at a given time? You got it, some of your requests are queued, until one of the connection is available to handle it.

That explains the need for multiplexing. One TCP connection to rule them all.

From Pipelining to HTTP/2

There is one attempt to overcome this issue in HTTP/1.1 which is HTTP pipelining. With pipelining, an HTTP client is able to send to a server multiple requests at once. The problem is that the requested HTTP server has to answer to all these requests, keeping the order in which they were made by the client. This mandatory requirement leads to a performance-limiting phenomenon known as Head-of-line-blocking.

To represent that, imagine that a client sends a request A involving a lot of computing server side, and a very easy to handle request named B. The server, which is able to deal with several requests at once will deal with the request B very quickly, but can’t send the response because it is waiting for the end of the A computation to respect the requests’ order. The slow requests become the limitation of all following requests.

Regular HTTP requests management vs HTTP pipelining
(https://en.wikipedia.org/wiki/HTTP_pipelining#/media/File:HTTP_pipelining2.svg)

This attempt was unsatisfactory, and so the need for a good multiplexing system on top of HTTP remains.

HTTP/2 enable multiplexing without the issues faced by the HTTP pipelining.

In HTTP/2, each request/response tuple is associated with a unique ID, and is called a stream. When the client sends a request, it gives it an ID, and that ID will be put in the server answer. Therefore, the client knows to which request the answer is, and there is no requirement of respecting the requests’ order like in HTTP pipelining. And therefore, no more Head-of-line-blocking anomaly!

Requests and responses belonging to different streams will flow through this unique HTTP/2 connection at a given time.

The HTTP/2 multiplexing
(https://developers.google.com/web/fundamentals/performance/http2)

Thanks for reading this article! If you want to know more about HTTP/2, the new article of this series about weight and dependency is now available here!

Alexandre for the Gatling team