HTTP (HyperText Transfer Protocol) is an application-level network protocol that determines how content is transferred over the network. HTTP/2 is its latest version as of the moment of this publication.
The specification of the first protocol version, HTTP/0.9, was published back in 1991. In 1996, HTTP/1.0 appeared, and HTTP/2’s predecessor, HTTP/1.1, was released in 1999. Then followed a long period without any updates.
An alternative to HTTP/1.1, the SPDY protocol, was developed in 2009. At that time, the developers already realized that the existing version was not providing for enough data transfer speed. The engineers strived to modify how the queries were sent and received, thus speeding up the work of the Internet. It was this protocol that HTTP/2 was based on.
SPDY really did speed up web apps. It was gaining popularity and provided serious competition to HTTP. Eventually the developers decided that there should not be two competitive protocols and ended up unifying the two standards. The HyperText Transfer Protocol work group from the Internet Engineering Task Force took up the new protocol creation, and in 2015, HTTP/2 was revealed.
The main goal of the new version was speeding up data transfer. At the same time, the developers wanted to eliminate the “bottlenecks” of HTTP/1.1, making it safer and more efficient.
As we already said, this protocol version was released in 1999, and HTTP/2 wasn’t created until 16 years later. A lot has changed on the Internet since. Many new website elements appeared: jаvascript, animations, CSS styles, and so on.
To make sure web resources loaded fast enough, queries for different elements had to be processed simultaneously. The protocol had to establish several TCP connections at once to transfer different kinds of data.
That created a colossal load on the network.
At the same time, the number of established connections was limited—and often not high enough. To bypass the limitations, web developers had to use a multitude of tricks, such as domain sharding (using subdomains to load resources), combining the pictures into a single file, and so on, which created further issues.
Besides, as HTTP/1.1 had existed for many years, at some point is stopped being safe. Intruders found loopholes in it, which allowed them to steal users’ data.
HTTP/2 solved all these problems and helped significantly speed up data transfer on the web.
To eliminate all the problems of HTTP/1.1, the developers introduced a number of important changes to the new version. We won’t examine each difference: let’s only talk about those that have a direct effect on the speed.
The previous versions of HTTP transferred data as text. It was convenient for the users, but from the technical point of view, text messages take longer to process than binary ones.
In HTTP/2, messages consist of frames, or binary data parts. Their sum total is called a stream. Every frame contains a unique stream ID: the information about what stream it is a part of.
There are several kinds of frames. For example, for the transfer of metadata (message size, data type, sender/receiver address, etc.), the HEADERS frame is used, while for the main message, it is the DATA frame.
Then there’s the RST_STREAM frame, which is used to terminate a stream: the client sends it to the server to announce that the stream is not needed anymore. It stops data transfer while keeping the connection open. To put that into context, in HTTP/1.1, the only way to stop data transfer was to terminate the connection, which then had to be reestablished.
These principles of binary protocol operation improve the connection quality:
Besides, the binary nature of HTTP/2 opened a whole range of possibilities to speed up data transfer, which we’ll discuss below.
This is one of the main differentiators of HTTP/2 from the previous versions, and the main feature that allowed the developers to speed up data transfer.
In HTTP/1.1, several parallel TCP connections were created for a quick transfer of different types of data. In the new version, all data can be transferred with a single connection.
The binary nature of the protocol makes it possible to load different kinds of information in parallel, without delays and without blocking any of the replies or queries.
Connection only has to be established once, and that really reduces the content delivery time. The reason is, a “three-way handshake” is required to establish each TCP connection:
Only after these three steps have been carried out, the connection is considered to have been established.
All of these steps take time. When the connection only needs to be established once, the computers do not waste time on extra “handshakes,” which increases the speed accordingly.
Besides, in HTTP/2, there is no need for domain sharding.
To avoid the limitation on the number of TCP connections in HTTP/1.1, developers posted some of the content onto the subdomains. The data from the subdomains was loaded in parallel, which helped increase the speed.
There’s no need to do that anymore: different data can be transmitted within a single connection, and there is no limitation.
To make sure the server completes the request as precisely as possible, its header should contain a lot of specifying metadata—and HTTP is a stateless protocol. That means the server cannot store the information from the previous requests, and the client ends up having to send a lot of identical data in headers.
These headers contain about 500 to 800 bytes of ancillary data—and if cookie files are used, it can be 1 KB+.
That makes the messages larger in general. And the larger the size of a message, the longer it is transferred, and the higher the delay will be.
In HTTP/2, the issue was fixed by header compression under the HPACK format. It encodes and compresses the headers using the Huffman algorithm. At the same time, the client and the server keep up a shared and constantly updated table of headers, which makes it possible to restore repeated headers from the table instead of sending them over and over.
Less data is being transferred, which means queries and replies are sent faster.
This feature allows the server to transfer data even before the client’s request. For example, the browser downloads a page and sends an HTML request. But to render the page, CSS data will be needed besides the HTML data. So, the server doesn’t wait for a second request for CSS and sends the CSS data immediately along with the requested data.
The data that the server “guessed” is sent within the PUSH_PROMISE frame: it allows the client to understand they didn’t request this information, and to determine whether they need it. If the information proves unnecessary (for example, because it is already cached), the browser can send as a response the RST_STREAM frame (we discussed it above) and stop the redundant data transfer.
This helps avoid data duplication.
Therefore, the feature lowers the number of requests to the server, lowers the load on it, and speeds up the operation of web apps.
By default, HTTP/2 data are sent asynchronously and in an arbitrary sequence. However, the sequence can be tuned. You can define what data the server should return first and what can be sent later.
The protocol makes it possible to determine the weight of each stream: its importance in the transfer priority plan. HTTP/2 also allows one to set up the interdependence of streams on one another.
The weight is determined as an integer from 1 to 256: the larger the number, the higher the priority of the stream.
The dependence of one stream on another is specified with a dedicated identifier, referring to another, “parent” stream.
For example, if stream X depends on stream Y, it means stream Y is the parent stream, and it must be fully processed first, before the processing of stream X begins.
If streams do not depend on one another but have different weights, different numbers of resources are allocated for each stream, proportional to their weight.
Suppose streams X and Y do not depend on one another, but the weight of X is 10, while the weight of Y is 15. Let’s calculate the share of resources to be allocated to each of them:
So, 40% of resources will be allocated for the processing of stream X, and 60%, for the processing of stream Y.
Let’s look at a more detailed example of how this works.
What this flow chart means is:
What opportunities prioritization provides:
A lot of time has passed since the release of HTTP/2, and it has been tested and compared to HTTP/1 many times. Different tests provide different results, but most of them do confirm that the new version is more productive than the predecessor.
For example, the CSS-Tricks test showed that a website with HTTP/2 loaded almost twice as fast as a HTTP/1.1 resource.
To perform this test, the company modeled a real single-page website on WordPress. To measure the load speed, they used the GTMetrix instrument.
As a result, with use of HTTP/1.1, the website page loaded in 1.9 seconds.
While with HTTP/2, under the same conditions, the load time was 1 second.
At the same time, we can see the number of queries under HTTP/2 was lower.
The results of a test performed by SolarWinds were not as impressive. It showed that HTTP/2 was only 13% more efficient than the predecessor.
Like in the previous test, the company measured the speed of a WordPress website with Pingdom. The speed was tested 4 times with 30-minute intervals. After averaging the results, here’s what they ended up with:
The HTTP/1.1 website loaded in 534 ms.
While with HTTP/2, the same website loaded in 464 ms.
In any case, HTTP/2 is currently the fastest and most optimized version of the Internet’s main data transfer protocol.
Gcore CDN supports the HTTP/2 protocol. And our network can transfer content over HTTP/2 even if your servers do not support it.
Gcore CDN specifics: