by Geronimo Tondato, Software Architect and Software Development at Edrans.
Here in Edrans we know the value of good old client-server architecture, as it still has a lot to offer in today’s world. In this article, we will go over the history and changes of one of the most relevant and widely used technologies in the industry.
Few things in tech have the honor of being alive and relevant for more than 25 years, today we are going to deep dive into one of those things. You may have heard about HTTP, right? I’m kidding, of course you have. Well, our beloved HTTP isn’t technically the same as 25 years ago, it has undergone updates and tweaks here and there to make it more suitable for nowadays use cases. The web has changed and so has HTTP. You may be surprised to know that there are different versions of HTTP: HTTP 1.0, HTTP 1.1, HTTP 2.0, and now we are quickly moving forward to HTTP 3.0.
But,why do we need all these versions of HTTP? And more importantly, what’s the difference between them?
Before diving in, let’s first introduce another player to the game: TCP. There is a tight relationship between HTTP and the TCP protocol: HTTP is an application layer protocol built on TCP, which means that in order to transmit data, a TCP connection between the client and the server has to be established first. This is the main design aspect that led to HTTP innovation; in other words, how to squish the most from that TCP connection? That is a question that has puzzled engineers over decades.
As end-users, we rarely have to deal with this:, we just want our web page to load and we want it fast. And that is the keyword that leads to all these updates: “fast”. In order to improve speed, clever techniques have been applied and there is a lot going on under the hood. Let’s open the hood and see what we find out.
The first version of HTTP was created in 1996. At the beginning, engineers thought that having a one-to-one relationship between HTTP and TCP was a cool idea. TCP connections are stateful, they take up memory space in the server and resources back then were scarce. In addition to this, the web was a very different place, sites were smaller and they used to consist mostly of text and one site usually meant one file. Thus, having to open one TCP connection per HTTP request looked like the way to go. Our HTTP 1.0 from 1996 looked something like this.
As you can see, it used to open a TCP connection, then made the HTTP request to ask for a resource in the server, for instance, “index.html” and finally it closed the connection. If subsequent resources were needed, a new TCP connection had to be established.
This approach didn’t last that long as engineers soon realized that things were getting slow due to the overhead of opening and closing TCP connections.
In 1997, HTTP 1.1 appeared in the scene, its most relevant feature being the ability to persist TCP connections between the client and the server even after an HTTP request had been completed. Now one TCP connection could be reused for more than one HTTP request. That was a great boost in performance for a web that was getting complex at that time. As you can see in the image below, once a TCP connection is established it can be used for multiple HTTP requests. But it still has a very important limitation: it can only be used for one request at a time. So, imagine you get the “index.html” in your first request and from there the client determines that it needs to load an icon, some style sheet, maybe some other script, and finally a bunch of images, all these resources had to be requested one by one, and the client had to wait for every response before making another one.
This scenario was less than ideal since the TCP connection was heavily underutilized. Unfortunately, things remained this way for a very long period of time, so web browsers started implementing a workaround to make the loading of pages faster.
HTTP 1.1 and the web Browser (the workaround)
Browsers “can tell” more often than not that one TCP connection is not going to make it. Since it is very likely that loading a specific page would require downloading multiple resources, engineers started to implement a smart workaround. When first establishing a connection with a server, the browser would actually initiate six TCP connections (it could vary a little bit from browser to browser). Now browsers had a pool of connections to request resources in parallel and things were looking better. This approach worked, it remained the standard for many years, but it still has limitations: what happens if there are more than six resources to be loaded in parallel? Well, they will have to wait for a free connection. As pages got more and more complex, this approach also proved to be insufficient. In 2015 a new release of HTTP was introduced to the game.
The major advantage that HTTP 2.0 brought about was its ability to do multiplexing. That is a fancy word to say that now, with one TCP connection, you can make as many HTTP requests as you want, all at once, without having to worry about what order the server responses come in. This is a better world, and the future’s looking brighter. Now HTTP requests and responses can travel freely through the TCP connection as shown in the image below. This approach is way better than what we used to have.
Although we would love to tell you that this is the end of the story and that HTTP 2.0 solved all our problems, unfortunately that is not the case. HTTP 2.0 is great, and it solved many problems but it also came with its own list of problems, the main one being the “Head-of-line blocking”. This led to the creation of HTTP 3.0, which is crazy stuff! It is not even based on TCP, it is actually a UDP protocol that comes with many advantages in speed and performance. But we will save the details for another article.