background

A lot of articles have been written about QUIC in the last year, but the problem is that they are all about what QUIC or HTTP3 is, and its advantages and mechanisms, and they praise it almost to the top. However, the person who has the heart will probably do some testing by hand, and will find that the performance of this much-vaunted thing is actually not as good as HTTP1.1, what is going on?

I’ve been working on QUIC or HTTP3 lately, and I’ve been trying to write an article like this to give a different answer to people who have the same question as me.

test

The test was simple. Two machines, both on the same LAN. The server uses the QUIC branch version of Nginx, nginx-Quic. The client uses H2Load (which supports the HTTP3 version) as the benchmark tool. The neTEM module is used on the server to manipulate the network status and simulate different network environments. The request has no request body and the response body is 612 bytes by default.

The parameters of H2load are as follows: -t 10 -c 100 -n 1000 -m 100:10 threads, 100 connections, and 1000 requests. Each connection can process 100 requests at the same time.

The HTTP version

delay

Packet loss rate

Repeat rate

Package damage rate

The results of

HTTP1.1

Total time 406.49ms, 24601.15 REq /s QPS, 21.30MB/s transmission

HTTP3

The total time is 611.90ms, 16342.59 REq /s QPS, 12.98MB/s transmission

HTTP1.1

100ms+-10

The total time is 1.90s, 5275.52 REQ /s QPS, 4.57MB/s transmission

HTTP3

100ms+-10

Total time 3.65ms, 2740.22 REq /s QPS, 2.18MB/s transmission

HTTP1.1

30%

Total time 33.64s, 297.28 REq /s QPS, 263.60KB/s transmission per second

HTTP3

30%

Total time 19.82s, 504.45 REq /s QPS, 447.31KB/s transmission per second

HTTP1.1

70%

The total time is 443.55ms, 23065.39 REQ /s QPS, 19.97MB/s transmission

HTTP3

70%

The total time is 419.98ms, 23810.43 REQ /s QPS, 18.92MB/s transmission

HTTP1.1

20%

Total time 14.46s, 691.61 REQ /s QPS, 613.27KB/s transmission per second

HTTP3

20%

Total time 4.12s, 2424.55 REQ /s QPS, 1.93MB/s transmission

HTTP1.1

100ms+-10

30%

The total time is 30.64s, 326.42 REq /s QPS, 289.44KB/s transmission per second

HTTP3

100ms+-10

30%

Total time 17.16s, 582.89 REQ /s QPS, 474.19KB/s transmission per second

HTTP1.1

30%

70%

The total time is 2.03s, 4914.90 REQ /s QPS, 4.26MB/s transmission

HTTP3

30%

70%

Total time 3.06s, 3264.89REq /s QPS, 2.59MB/s transmission

HTTP1.1

30%

20%

Too slow to work…

HTTP3

30%

20%

Total time 15.09s, 662.75 REq /s QPS, 539.16KB/s transmission per second

In this test, I gave the typical values, but I also did some resizing to see the results. From the results we can see the following conclusions:

  1. Increasing latency alone does not make HTTP3 better than HTTP1.1.

  2. The performance advantage of HTTP3 over HTTP1.1 increases significantly as the packet loss rate increases.

  3. Increasing packet repetition rates alone HTTP3 has only a slight advantage over HTTP1.1.

  4. Increasing the packet damage rate alone will significantly increase HTTP3’s performance advantage over HTTP1.1.

  5. Delays occurring at the same time as other factors did not have a greater impact on the overall results.

  6. Packet duplication and damage (or loss rate) are a set of opposing projects. Loss or damage reduces the number of available packets, but the repetition rate makes up for the loss, resulting in a better result for HTTP1.1.

From the above conclusions, we can see that HTTP3 is not always better than HTTP1.1, but for weak networks with high packet loss rate, packet loss, QUIC or HTTP3 advantage is very obvious, thanks to its FEC mechanism and connection reuse mechanism. However, in life, there are many weak network environments, such as subway stations, elevators, some buildings, and some towns with incomplete network coverage, etc. So QUIC is more of a pocketbook strategy for the overall network.

Therefore, it would be unwise to upgrade all requests to the HTTP3 version using the default configuration of Nginx-Quic, since the performance benefits of HTTP1.1 in general are not negligible. This introduces the components in the next section.

component

From the above conclusion, we found that it is not a good idea to upgrade every request, so there is this Nginx module to automate version upgrades — ngx_http_autoquic_module

This module determines whether the HTTP version needs to be upgraded to HTTP3 based on the TCP network conditions. According to QUIC statistics to determine whether you need to downgrade to HTTP1.1 version. Since demoting is not as smooth as upgrading, a switch has been added to demoting so that the user can choose whether to allow demoting or not.

Promotion and degradation are currently well supported for browsers. For many clients, however, it depends on the processing logic of the HTTP library used by the client.

Thanks for reading and I look forward to your comments.