Testing nginx rewrite performance
By Tom In nginxOur website is 12 years old and over time we have accured quite a few URL changes. Mainly due to terminlogy changes and SEO restructures. 819 to be exact. They are rewrite
rules in a nginx config file. This is a lot of regular expressions that nginx needs to execute every request. We were interested in the performance impact so we did a quick test.
We created a minimum nginx config:
$ cat /home/tom/nginx_test/nginx.conf
events {
use epoll;
}
error_log off;
http {
access_log off;
# This folder will have our rewrite rules in it
include /etc/nginx/rewriterules/*;
server {
listen 80;
# a self-contained endpoint without any dependencies on other services.
location / {
expires -1; # Disable client caching (Output Header: Cache-Control: no-cache)
default_type text/plain;
return 200 ready;
}
}
}
Lets check it works
$ docker run --name loadtest -v /home/tom/nginx_test/nginx.conf:/etc/nginx/nginx.conf:ro -d -p 49666:80 nginx;
$ wget -qO- http://127.0.0.1:49666/
ready
ok, we’re ready for our first test, which is the base-case, i.e. 0 redirects. We’ll use vegeta to time the latency over 10,000 requests.
$ date;echo 'GET http://127.0.0.1:49666/' | vegeta attack -rate=1000 -duration=10s | vegeta report
Sat 2 May 07:46:32 BST 2020
Requests [total, rate, throughput] 10000, 1000.12, 1000.10
Duration [total, attack, wait] 9.999s, 9.999s, 170.026µs
Latencies [min, mean, 50, 90, 95, 99, max] 99.415µs, 154.843µs, 132.126µs, 197.848µs, 292.922µs, 498.15µs, 3.898ms
Bytes In [total, mean] 50000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:10000
For test 2, we’ll add 819 rewrite rules to nginx and test again. I won’t show all our rewrite rules but here is a small extract to show an example of the kind of thing we’re talking about:
$ cat /home/tom/nginx_test/rewriterules.conf
...
rewrite ^/site/aboutus$ https://$http_host/about permanent;
rewrite ^/static/how-it-works-buyer$ https://$http_host/how-it-works permanent;
rewrite ^/static/how-it-works-seller$ https://$http_host/how-it-works permanent;
rewrite ^/site/joinus$ https://careers.jobscore.com/careers/peopleperhourcom permanent;
...
Lets run the same test, 10,000 requests again but this time I mount the rewriterules.conf
into the nginx docker container:
$ docker stop loadtest;docker rm loadtest;docker run --name loadtest -v /home/tom/nginx_test/nginx.conf:/etc/nginx/nginx.conf:ro -v /home/tom/nginx_test/rewriterules.conf:/etc/nginx/rewriterules.conf -d -p 49666:80 nginx;
$ date;echo 'GET http://127.0.0.1:49666/' | vegeta attack -rate=1000 -duration=10s | vegeta report
Sat 2 May 07:25:59 BST 2020
Requests [total, rate, throughput] 10000, 1000.11, 1000.09
Duration [total, attack, wait] 9.999s, 9.999s, 197.294µs
Latencies [min, mean, 50, 90, 95, 99, max] 144.79µs, 191.594µs, 172.16µs, 217.622µs, 255.267µs, 562.041µs, 3.485ms
Bytes In [total, mean] 50000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:10000
The median latency has worsened from 132.126µs to 172.16µs. This is peanuts, but it shows the extra rewrites are having a impact to performance, however small.
Lets finish up by trying a really large number of rewrites. I took my rewriterules.conf
file, did select-all, then copy and paste, paste, paste*10 until I had 10,000 rules. I ran exactly the same command as the previous test:
$ docker stop loadtest;docker rm loadtest;docker run --name loadtest -v /home/tom/nginx_test/nginx.conf:/etc/nginx/nginx.conf:ro -v /home/tom/nginx_test/rewriterules.conf:/etc/nginx/rewriterules.conf -d -p 49666:80 nginx;
$ date;echo 'GET http://127.0.0.1:49666/' | vegeta attack -rate=1000 -duration=10s | vegeta report
Sat 2 May 07:29:11 BST 2020
Requests [total, rate, throughput] 10000, 1000.11, 1000.01
Duration [total, attack, wait] 10s, 9.999s, 934.258µs
Latencies [min, mean, 50, 90, 95, 99, max] 801.745µs, 8.855ms, 906.9µs, 28.047ms, 51.096ms, 74.329ms, 467.309ms
Bytes In [total, mean] 50000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:10000
The results
With no rewrites a page is served in 132.126µs. With 819 rewrites a page is served in 172.16µs. With 10,000 rewrites a page is served in 906.9µs.
The conclusion
Ngix rewrites are super fast, use as many as you want because the performance impact is negligible. We’re talking nano-seconds.
No Comment