-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement http3 #42
Comments
Update:Spoke with @DiegoRBaquero to tackle this issue. We concluded that:
Test Setup:
Both servers use the same SSL certs and both serve the same generic HTML file. Tests were run for a fixed duration of 10mins. The number of concurrent users was changed for each test. *Results *: NOTE: These results are now stale, please check comments below for updated results
|
Interesting that the failure rate was 0 with Caddy but significant with Nginx 🤔 |
@gruns @DiegoRBaquero Update on this issue. I noticed that I was pinging each service using a different host on my local machine. I changed it to be the same for both of them, which is the docker host for the benchmarking tool I was running. I re-ran all the tests with the same setup and the results now tell a different story on Caddy's HTTP/3 capabilities. At 300 concurrent clients, we half the TTFB compared to Nginx. One odd thing is that Nginx's failure rate decreases as the load increases on the webserver.
|
@gruns @DiegoRBaquero I also setup a docker image that runs our nginx setup with http3 setup. The image is in the http-testing repo here. For some reason, nginx's HTTP3 implementation is much slower than what we have right now. I contacted on of the developers and they mentioned that QUIC on nginx will probably not be ready until end of 2023. Here are some of the testing results:
|
Update 2I ran more tests by deploying Nginx and Caddy on AWS lightsail instances in Frankfurt (eu-central-1).
With 5 Concurrent Clients:
With 30 Concurrent Clients:
With 100 Concurrent Clients:
|
promising!! 🎉 what's the ping/RTT between you (the client) and the frankfurt lightsail instance (the server)? also interesting that its inconsistent whether caddy or nginx is faster, depending on the # of concurrent clients. at 5 and 30 concurrent clients, nginx's http3 ttfb (220ms, 250ms) is faster than caddy's http3 ttfb (330ms, 380ms), but at 100 concurrent clients caddy's http3 ttfb (450ms) is lower than nginx's http3 ttfb (750ms). interesting. and weird. 🤔 also nginx's http3 ttfb (750ms) was way worse than nginx's http2 ttfb (450ms) at 100 concurrent clients. besides that one measurement (nginx's http3 ttfb at 100 concurrents) the data makes sense and http3's ttfb is lower across the board for all # of concurrents for both nginx and caddy
jk. likely not an abberation. from looking at the local benchmarks posted above, nginx's http3 implementation seems to choke on high numbers of concurrent clients. as shown in these benchmarks:
|
@gruns Pinged poth servers using Result from terminal:
|
next questions:
|
Update 4:@gruns Addressing some of the questions above: Once an HTTP3 connection is established, does the browser remember that for subsequent connections?:
Benchmarks for 1 Client:
Does the benchmarking tool open new connections for each request?:
How ready is nginx's http3?:
What work needs to be done to benchmark http3 vs http2 in our test network?:
Can a page, which loaded over http2 (ie a page with arc), request an asset from another domain, eg strn.pl, over http3?
|
sickkkk. remaining todos now for @joaosa with the baton 💪:
@joaosa once you get a sense of the above items, sync with me (@gruns) on an estimated timeline for the above 👍 |
Alright, I ran some benchmarks with Envoy and HAProxy acting as reverse-proxies and with simplehttp2server as their backend. I tried to replicate Amean's setup in order to have "comparable" results (refer to here). I ran the benchmarking tool (h2load) from my machine towards a couple of lightsail Ubuntu 20.04 machines I deployed. I'm going to comment on the results scenario by scenario (http2 vs http3), explain a couple of things I tried and then go for the final benchmarks. HAProxy h3 vs h2
|
Service | Protocol | TTFB Mean | Failure Rate | Reqs/S | Concurrent Clients |
---|---|---|---|---|---|
Caddy | HTTP/3 | 448.59ms | 0.00% | 32.59 | 100 |
Nginx | HTTP/3 | 751.78ms | 0.02% | 67 | 100 |
Envoy | HTTP/3 | 448.12ms | 0.00% | 11.16 | 100 |
HAProxy | HTTP/3 | 689.34ms | 0.00% | 14.24 | 100 |
Envoy | HTTP/3 | 845.13ms | 0.00% | 5.89 | 200 |
HAProxy | HTTP/3 | 1.26s | 0.00% | 7.73 | 200 |
Envoy | HTTP/3 | 1.24s | 0.00% | 4.08 | 300 |
HAProxy | HTTP/3 | 1.88s | 0.00% | 4.94 | 300 |
Envoy's TTFB values seem pretty decent given what we've seen in terms of h3 overall (it uses Cloudflare's quiche). Also, the devs say "HTTP/3 downstream support is ready for production use, but continued improvements are coming (...)" over here.
HAProxy appears to be doing less well, but with a slightly higher throughput.
One aspect I'm concerned about in both scenarios is perceived throughput, which seems to be lower than with NGINX/Caddy.
Given I'm using an reverse-proxy backend (with h2) for both HAProxy and Envoy, results may not be exactly comparable as there is another moving piece whose performance could be impacting the results. What are your thoughts on this?
Either way, I warrant these are good enough reasons to try Envoy (and possibly HAProxy) out in more realistic scenarios. What do you all think?
I decided to benchmark nginx as well to allow for comparisons following the same methodology as described above. I added a proxy backend for nginx. We're not caching responses, so as to get fairer values. I should note I'm using httpd as a http1.1 backend here. Nginx h3 (without
|
Service | Protocol | TTFB Mean | Failure Rate | Reqs/S | Concurrent Clients |
---|---|---|---|---|---|
Nginx | HTTP/3 | 326.88ms | 0.00% | 8.53 | 100 |
Envoy | HTTP/3 | 448.12ms | 0.00% | 11.16 | 100 |
HAProxy | HTTP/3 | 689.34ms | 0.00% | 14.24 | 100 |
Nginx | HTTP/3 | 589.88ms | 0.00% | 2.21 | 200 |
Envoy | HTTP/3 | 845.13ms | 0.00% | 5.89 | 200 |
HAProxy | HTTP/3 | 1.26s | 0.00% | 7.73 | 200 |
Nginx | HTTP/3 | 884.57ms | 0.00% | 2.67 | 300 |
Envoy | HTTP/3 | 1.24s | 0.00% | 4.08 | 300 |
HAProxy | HTTP/3 | 1.88s | 0.00% | 4.94 | 300 |
@joaosa Really interesting results. The |
Let's look into concurrent streams (where m=10nginx
Interesting to see how performance degraded substantially here. envoy
Performance degraded. haproxy
Performance degraded. m=50nginx
Worse than envoy
Worse than haproxy
Worse than m=100nginx
Way worse than envoy
Similar to haproxy
We get really low throughput or no results at all. Preliminary max concurrent streams conclusionsIncreasing the number of max concurrent streams seems to have a negative impact on both Nginx and HAProxy. That was the case on Envoy (from 1 to 50), but then it seemed to stabilize. Here's the summary:
The surprisingly high throughput for Envoy is explained by the substantial amount of failed requests (which was consistent over multiple runs). It looks like all solutions deal poorly with an increasing amount of max concurrent streams. Nginx seems to be the most reliable in terms of throughput and TTFB in this scenario. backend = httpd (http/1.1)Note this was the case for nginx from the start. envoy
haproxy
Max concurrent streams conclusionsSwitched everyone to have httpd (http/1.1) upstream, so the test scenario got absolutely even.
|
Preliminary GSO enabled resultsDecided to verify if enabling GSO would affect performance values for maximum concurrent streams given the poor results. The idea came from this blog post. For now, I only tried nginx as it was the best performer (also the most comparable to itself as I only used one backend for it in these benchmarks). See the posts above. I enabled GSO with nginx with
|
Service | Protocol | M | TTFB Mean | Failure Rate | Reqs/S | Concurrent Clients | Tweaks |
---|---|---|---|---|---|---|---|
Nginx | HTTP/3 | 1 | 331.06ms | 0.00% | 8.08 | 100 | GSO+rmem |
Nginx | HTTP/3 | 1 | 326.88ms | 0.00% | 8.53 | 100 | rmem |
Nginx | HTTP/3 | 10 | 1.07s | 1.00% | 8.96 | 100 | GSO+rmem |
Nginx | HTTP/3 | 10 | 1.25s | 1.00% | 9.39 | 100 | rmem |
Nginx | HTTP/3 | 50 | 2.17s | 3.00% | 10.16 | 100 | GSO+rmem |
Nginx | HTTP/3 | 50 | 2.22s | 3.00% | 9.67 | 100 | rmem |
Nginx | HTTP/3 | 100 | 1.71s | 6.00% | 9.31 | 100 | rmem |
Nginx | HTTP/3 | 100 | 1.80s | 5.00% | 10.14 | 100 | GSO+rmem |
Nginx | HTTP/3 | 100 | 2.01s | 8.00% | 8.70 | 100 | GSO |
Results seem better for GSO+rmem, but the differences aren't enough to exclude sampling error. I find this inconclusive, but if I had to choose I would take both tweaks.
http3 could be a huge, quick bang for our buck to significantly improve ttfb without adding more nodes/PoPs
adding http3 support should be broken into three pieces:
do a quick benchmark of nginx's tcp+tls vs http3. for example, fire up an aws ec2 instance far away and run two web servers there, one standard tcp+tls with nginx and the other with quic/http3. then benchmark how long it takes to establish connections to each of those web servers in a browser that supports http3, like chrome (https://caniuse.com/http3)
http3 should be much faster. but is it? this can also serve as a quick test-bed of the variegated http3 tools, libraries, and software that exist right now. see below
ping @DiegoRBaquero to get a production ssl cert to use
understand the architecture of the l1 and investigate the http3 landscape to determine the best tool, library, or software to add http3 support to the l1. various tools:
caddy -> nginx -> l1 shim
fwiw nginx v1.16 is 3 years old and EOL'd two years ago https://endoflife.date/nginx
litespeed -> nginx -> l1 shim
. fwiw according to https://w3techs.com/technologies/segmentation/ce-quic/web_server the majority of quic traffic online is currently served from litespeed. though if cloudflare supports http3, which it supposedly does, these stats dont make sense unless cloudflare uses litespeed. which they dontdiscuss viable avenues for http3 implementation with @gruns and @DiegoRBaquero
note here that, for simplicity, any non-nginx http3 implementation will likely be replaced with nginx's native http3 support once ready, so long as nginx's implementation suffices. so we shouldn't get too crazy adding http3 support wrt the amount of time, effort, or complexity undertaken here
once http3 has shown itself superior and we've determined the implementation battleplan, add http3 support to the l1 node and ship it, baby 🚀
The text was updated successfully, but these errors were encountered: