LigHTTPd and Apache - Symfony benchmarks

Updated:

Note : This page may contain outdated information and/or broken links; some of the formatting may be mangled due to the many different code-bases this site has been through in over 20 years; my opinions may have changed etc. etc.

At work, we’re developing a brand new in-house CMS based on the Symfony framework. As it uses no mod_rewrite rules or other Apache dependencies and is a "clean break" for us, I figured it would be an ideal candidate for benchmarking under LigHTTPd, comparing it to Apache 2.2 in order to give me some statistics to compliment my last blog entry on the subject.
The results from the "ab" Apache-benchmark tool are pretty stunning - although I’m still at a loss as to explain just why LigHTTPd is so much faster. The configuration of everything apart from the webserver is identical. I’m running on a Sun Ultra 20 with 2Gb of RAM and Solaris 10 01/06. I have a shared document root, and two separately, identically configured zones, one running Apache 2.2.3 with prefork MPM, the other running LigHTTPd. PHP on both is 5.1.4, built using exactly the same compiler (Sun Studio 11) and flags for the Apache 2.2 SAPI and Fast-CGI build. Apache is using PHP loaded as a DSO, whilst LigHTTPd is running PHP through a socket, with 8 pre-forked PHP child processes :

fastcgi.server = (
".php" => ((
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/local/php/bin/php",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "8",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"min-procs" => 1,
"max-procs" => 1,
))
)

The page in question is just the initial login page to the CMS. There’s no database access at all, so no communication with any system external to the web server. It’s just straight Symfony processing, using the current trunk. Read on for the results…

I first ran ab with a concurreny of 3, for 50 requests in total. Apache results <pre>Concurrency Level: 3
Time taken for tests: 7.845 seconds
Complete requests: 50
Failed requests: 0
Broken pipe errors: 0
Total transferred: 241250 bytes
HTML transferred: 220150 bytes</pre><pre>Requests per second: 6.37 [#/sec] (mean)
Time per request: 470.70 [ms] (mean)
Time per request: 156.90 [ms] (mean, across all concurrent requests)
Transfer rate: 30.75 [Kbytes/sec] received</pre><pre>
Connnection Times (ms)</pre><pre> min mean[+/-sd] median max</pre><pre>Connect: 0 0 0.0 0 0
Processing: 154 449 291.7 415 1357
Waiting: 154 449 291.8 414 1357
Total: 154 449 291.7 415 1357</pre>LigHTTPD results

Concurrency Level:      3
Time taken for tests: 2.927 seconds
Complete requests: 50
Failed requests: 0
Broken pipe errors: 0
Total transferred: 236600 bytes
HTML transferred: 220150 bytes
Requests per second:    17.08 [#/sec] (mean)
Time per request: 175.62 [ms] (mean)
Time per request: 58.54 [ms] (mean, across all concurrent requests)
Transfer rate: 80.83 [Kbytes/sec] received

Connnection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0     0    0.2      0     2
Processing: 57 106 146.8 59 809
Waiting: 57 105 146.9 58 808
Total: 57 106 146.8 59 809

Analysis LigHTTPd clearly wins on this one, both in terms of overall time, and the number of requests it managed to handle per second. I was interested to see how well it scaled though, so upped the number of requests to 1,000 and concurrency to 20. The difference is even more pronounced : Apache Summary

Time taken for tests:   169.914 seconds
Total transferred: 4825000 bytes
HTML transferred: 4403000 bytes
Requests per second: 5.89 [#/sec] (mean)
Time per request: 3398.28 [ms] (mean)
Time per request: 169.91 [ms] (mean, across all concurrent requests)
Transfer rate: 28.40 [Kbytes/sec] received

Lighttpd Summary

Time taken for tests:   58.354 seconds
Total transferred: 4732000 bytes
HTML transferred: 4403000 bytes
Requests per second: 17.14 [#/sec] (mean)
Time per request: 1167.08 [ms] (mean)
Time per request: 58.35 [ms] (mean, across all concurrent requests)
Transfer rate: 81.09 [Kbytes/sec] received

Now, that’s impressive. Just compare the number of requests a second, transfer rate and overall time taken for the tests. LigHTTPd blows Apache away, and what’s just as interesting is what’s going on behind the scenes. Apache sustained 60-70% CPU utilisation and around 300Mb RSS size during that run, LigHTTPD and the FastCGI processes stuck at a constant 118Mb RSS. CPU utilisation did peak up to 70% at top, but was around 40% for most of the test. Conclusion I’m even more impressed with LigHTTPd now I have some numbers to back me up, yet I’m still at a loss as to explain exactly why it is so much fast. Could it be that Apache adds an even greater overhead to PHP running as a DSO module ? We already know LigHTTPd is far batter than Apache at serving static content and it’s general efficiency is better; but that’s nothing particularly new, people have been offloading static content from Apache for years. But it looks like it could really make a massive difference to dynamic content as well. Time to do some more investigating…