<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Benchmarking on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/benchmarking/</link><description>Recent content in Benchmarking on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 06 Jan 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/benchmarking/index.xml" rel="self" type="application/rss+xml"/><item><title>Perils of Benchmarking</title><link>https://blog.iankulin.com/perils-of-benchmarking/</link><pubDate>Mon, 06 Jan 2025 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/perils-of-benchmarking/</guid><description>&lt;p&gt;I&amp;rsquo;ve been containerising my websites, with their servers to make deployment simple and robust, and to move to a CI/CD workflow. Since an install of a production web server is large, I would be running about ten of these containers, and there&amp;rsquo;s already a good server facing the net and doing the reverse-proxying (NGINX Proxy Manager), I chose to bundle the Busy-Box httpd server with my sites inside the Docker containers.&lt;/p&gt;
&lt;p&gt;I had a vague feeling that there was a performance vs size compromise involved, and during some googling found this &lt;a href="https://github.com/nerkn/nginx-busybox-apache/tree/main"&gt;github repo&lt;/a&gt; where nerkn has bench-marked busy-box vs apache vs nginx with, to me (because of my choice above), alarming results.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-11-16-at-10.37.19-am.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;If NGINX is doing twice the throughput, and is two orders of magnitude quicker, then busy-box is not going to be a good choice for me.&lt;/p&gt;
&lt;p&gt;Before I panicked, I thought I&amp;rsquo;d do my own A/B tests, which since it&amp;rsquo;s containerised is simple. I used the &lt;a href="https://httpd.apache.org/docs/2.4/programs/ab.html"&gt;apache &lt;code&gt;ab&lt;/code&gt; testing tool&lt;/a&gt; - it spits out the basics - times for connecting, processing, and waiting. It does multiple tests and gives you the mean and standard deviation for them. Perfect.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the results for a series of tests. I included a commercial website I suspect is in the same data centre as a sanity check.&lt;/p&gt;
&lt;table class="has-fixed-layout"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Test&lt;/td&gt;&lt;td&gt;Mean time (ms)&lt;/td&gt;&lt;td&gt;St dev&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nextdc.com.au&lt;/td&gt;&lt;td&gt;834&lt;/td&gt;&lt;td&gt;293&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;busy-box uclibc&lt;/td&gt;&lt;td&gt;450&lt;/td&gt;&lt;td&gt;93&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;busy-box uclibc&lt;/td&gt;&lt;td&gt;411&lt;/td&gt;&lt;td&gt;24&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nginx-alpine&lt;/td&gt;&lt;td&gt;423&lt;/td&gt;&lt;td&gt;24&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nginx-alpine&lt;/td&gt;&lt;td&gt;410&lt;/td&gt;&lt;td&gt;26&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;busy-box uclibc&lt;/td&gt;&lt;td&gt;398&lt;/td&gt;&lt;td&gt;19&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;busy-box uclibc&lt;/td&gt;&lt;td&gt;419&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nginx-alpine&lt;/td&gt;&lt;td&gt;403&lt;/td&gt;&lt;td&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nginx-alpine&lt;/td&gt;&lt;td&gt;398&lt;/td&gt;&lt;td&gt;23&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;nextdc.com.au&lt;/td&gt;&lt;td&gt;759&lt;/td&gt;&lt;td&gt;306&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Huh. A couple of things jump out. One is that the site is probably fast enough, and the other is that the performance of busy-box and NGINX are similar, like very suspiciously similar. I wonder what happens if I &lt;code&gt;docker compose down&lt;/code&gt; the website and run the test again?&amp;hellip;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;This is ApacheBench, Version 2.3 &amp;lt;$Revision: 1903618 $&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Licensed to The Apache Software Foundation, http://www.apache.org/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Concurrency Level: 10
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Time taken for tests: 4.608 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Complete requests: 100
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Failed requests: 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Non-2xx responses: 100
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Total transferred: 30300 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HTML transferred: 15400 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Requests per second: 21.70 [#/sec] (mean)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Time per request: 460.777 [ms] (mean)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Time per request: 46.078 [ms] (mean, across all concurrent requests)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Transfer rate: 6.42 [Kbytes/sec] received
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Connection Times (ms)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; min mean[+/-sd] median max
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Connect: 274 318 33.6 306 451
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Processing: 82 95 14.5 92 170
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Waiting: 82 95 14.3 92 169
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Total: 362 413 37.5 401 580
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;lol. Okay. I guess I&amp;rsquo;ve been testing the cache in NGINX Proxy Manager this whole time. There is a setting for that, so perhaps I should turn that off. Sadly, even with that turned off, and the container not running, I&amp;rsquo;m still getting that good performance which would be the 500 error coming back from NGINX Proxy Manager.&lt;/p&gt;
&lt;p&gt;Time to trick it into not using the cache by making unique requests each time. I&amp;rsquo;ll use these:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ab -n 100 -c 10 &amp;#34;https://example.com.au/index.html?nocache=$(date +%s%N)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ab -n 100 -c 10 &amp;#34;https://www.nextdc.com/index.html?nocache=$(date%20+%s%N)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m also able to see that it&amp;rsquo;s hitting the container with all the requests by running the compose up in the foreground and having the logs output. So now I&amp;rsquo;m much more confident about the output. Here&amp;rsquo;s the summary of a much larger group of tests run in that round robin style.&lt;/p&gt;
&lt;table class="has-fixed-layout"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Situation&lt;/td&gt;&lt;td&gt;Mean time (ms)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nextdc.com&lt;/td&gt;&lt;td&gt;617&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NGINX Proxy with no site&lt;/td&gt;&lt;td&gt;412&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NGINX-apline site&lt;/td&gt;&lt;td&gt;420&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Busy-box (uclibc)&lt;/td&gt;&lt;td&gt;424&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The comparison with nextdc is of course unfair. They are returning a lot more html, and some of it could be server rendered. I don&amp;rsquo;t have an explanation of why my results are so different from nerkn&amp;rsquo;s. He&amp;rsquo;s using a different tool, and I imagine on a local network (mine is over a mobile data link, to a VPS in a data centre).&lt;/p&gt;
&lt;p&gt;As far as the container size comparisons go, the NGINX-alpine one is 48.98MB and the uclibc version of BusyBox is 1.35MB. I think I&amp;rsquo;ll be sticking with that.&lt;/p&gt;</description></item></channel></rss>