Benchmarks

Cherokee is really really fast. The speed at which any web server can serve requests for content is both directly tied to and limited by the I/O speed of underlying hardware and operating system. In this regard, a web server's performance is measured by the latency incurred after an I/O request to the underlying system has completed.

The primary objective of the Cherokee project is to reduce to zero the latency incurred between the time a dynamic or static system I/O request has completed and the time the resulting content is served to the requesting client. Admittedly, a very tough goal to reach.

In fact, it might be impossible. But achieving that which was once seen as impossible is what drives innovation. And it's innovation that drives the ongoing development of the Cherokee project, bringing us closer to the impossible with each new release.

To show the project's progression towards the ultimate goal, whenever a benchmark is performed it will be published right here. Older releases had impressive but not very thorough benchmarks. Whenever it is possible the conditions of the benchmark will be provided so that anyone can replicate the results. That is, after all, an essential basis of the Scientific method.










Cherokee 0.10.0

This benchmark was originally published at Alvaro's blog in a post under the title: The fastest and best designed among the modern web servers

Benchmarking software is not an easy thing to do. It may look trivial, but it requires a bast amount of time and effort when you want to do it right.

In this case, I've been working on a series of web server benchmarks. The target was to measure how the modern web servers perform in different scenarios: different contents, requests, load, and even different hardware.

Most of our previous benchmarks were based on the result of ab requesting a few hundred thousand times the very same file, and that isn't obviously measuring how the server would perform in a real production environment.

So, in this post I'm going to present the result of a more realistic benchmark. This time, instead of requesting a single file, there were 300 different files for the clients to request. Files were between 156 bytes and 14MB.

By the way, as you may have noticed, I said that I'd benchmark the "modern web server". That's an important point. I have chosen to benchmark: Cherokee, Lighttpd and Nginx. All the rest did not made it to be included; the two most notorious cases:

So, without any further delay, here you have the results: (X=concurrent clients, Y=reqs/s)

Note that the difference between Cherokee and the rest increases with the number of concurrent clients. That means that it'll be the best performing web server while your client number raises (when you need it the most, actually).

So, as you can see, Cherokee is the fastest and best designed among the modern web servers. But it's even better than that. The next benchmark will be focused on dynamic content delivery, and it will show how Cherokee outperforms all the rest by even a bigger difference. Stay tuned!

Edit (Sat Oct 18 17:16:23 CEST 2008): For the sake of correctness, here you have a couple of scripts (1, 2), and configuration files (1, 2, 3) that the benchmark has been based upon.


Cherokee 0.8.1 benchmark

This is just a quick benchmark made by Alvaro to have something to show on the release date. Better, more representative benchmarks should be added shortly.

Today, after releasing Cherokee 0.8.1 I decided it was time to test again how it was doing about performance. In the last months we have got a great new I/O cache layer and a couple of structural changes that were supposed to have a positive impact on the general server performance, although nobody checked whether those changes were as effective as we aimed them to be.

So, once again, here I am bringing good news. We have done it. Cherokee is actually the fastest web server among a set of the most common servers nowadays: Apache, Cherokee, Lighttpd and Nginx!!

The benchmark consisted on half a million requests of a 1.7KiB static file, with 20 concurrent clients, using a 1Gbit/s local network. The results (fastest to slowest) were:

Cherokee:

Server Software:        Cherokee/0.8.1
Server Hostname:        10.0.0.102
Server Port:            80

Document Path:          /index.html
Document Length:        1795 bytes

Concurrency Level:      20
Time taken for tests:   17.819725 seconds
Complete requests:      500000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    500000
Total transferred:      999007442 bytes
HTML transferred:       897506630 bytes
Requests per second:    28058.79 [#/sec] (mean)
Time per request:       0.713 [ms] (mean)
Time per request:       0.036 [ms] (mean, across all concurrent requests)
Transfer rate:          54747.93 [Kbytes/sec] received

Lighttpd:

Server Software:        lighttpd/1.4.19
Server Hostname:        10.0.0.102
Server Port:            80

Document Path:          /index.html
Document Length:        1795 bytes

Concurrency Level:      20
Time taken for tests:   21.248000 seconds
Complete requests:      500000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    470598
Total transferred:      991856958 bytes
HTML transferred:       897503590 bytes
Requests per second:    23531.63 [#/sec] (mean)
Time per request:       0.850 [ms] (mean)
Time per request:       0.042 [ms] (mean, across all concurrent requests)
Transfer rate:          45585.94 [Kbytes/sec] received

NginX:

Server Software:        nginx/0.5.33
Server Hostname:        10.0.0.102
Server Port:            80

Document Path:          /index.html
Document Length:        1795 bytes

Concurrency Level:      20
Time taken for tests:   23.741872 seconds
Complete requests:      500000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    500000
Total transferred:      1006000217 bytes
HTML transferred:       897500000 bytes
Requests per second:    21059.84 [#/sec] (mean)
Time per request:       0.950 [ms] (mean)
Time per request:       0.047 [ms] (mean, across all concurrent requests)
Transfer rate:          41379.30 [Kbytes/sec] received

Apache2.2:

Server Software:        Apache/2.2.8
Server Hostname:        10.0.0.102
Server Port:            80

Document Path:          /index.html
Document Length:        1795 bytes

Concurrency Level:      20
Time taken for tests:   35.438605 seconds
Complete requests:      500000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    495064
Total transferred:      1043777896 bytes
HTML transferred:       897500000 bytes
Requests per second:    14108.91 [#/sec] (mean)
Time per request:       1.418 [ms] (mean)
Time per request:       0.071 [ms] (mean, across all concurrent requests)
Transfer rate:          28762.81 [Kbytes/sec] received

For the record: I did my best configuring all the servers in the very same way. In all the cases I removed unnecessary rules that could have slowed down the server (checks for htpasswd files and so on). And all the binaries came from the Debian repository, except for Cherokee 0.8.1 that hasn't been packaged yet.

Anyway, this benchmark has been just a quick test. It is not certainly representing the result that these servers would have handling real traffic though. So, in the following days I will try to do a new a more accurate benchmark with static and dynamic content, compression, redirections, etc. I'm pretty sure the results will be even better.


Cherokee 0.6

This benchmark was performed by Miguel Angel Ajo Pelayo with Django running on Cherokee 0.6.0 and Apache 2.0.40. It shows Cherokee as a clear winner serving dynamic content. Specifically three times as much! And you haven't yet seen static results. The advantage is a lot bigger.


Date:    2008-03-10 23:24
Subject: [cherokee-dev] Django & Apache migration to Django & Cherokee 0.6 x3 speed!!! :D

Phewww, incredible:

This was Apache:

ab -n 200 -c 50 http://leemelo.com/feeds/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking leemelo.com (be patient)
Completed 100 requests
Finished 200 requests


Server Software:        Apache/2.2.3
Server Hostname:        leemelo.com
Server Port:            80

Document Path:          /feeds/
Document Length:        13803 bytes

Concurrency Level:      50
Time taken for tests:   6.581932 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      2811600 bytes
HTML transferred:       2760600 bytes
Requests per second:    30.39 [#/sec] (mean)
Time per request:       1645.483 [ms] (mean)
Time per request:       32.910 [ms] (mean, across all concurrent requests)
Transfer rate:          417.05 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:   222 1369 1660.9    474    6581
Waiting:      222 1368 1660.8    474    6580
Total:        222 1369 1660.9    474    6581

Percentage of the requests served within a certain time (ms)
  50%    474
  66%    821
  75%   2099
  80%   3247
  90%   3726
  95%   4657
  98%   6401
  99%   6492
 100%   6581 (longest request)

And this is Cherokee:

ab -n 200 -c 50 http://leemelo.com/feeds/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 > apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking leemelo.com (be patient)
Completed 100 requests
Finished 200 requests


Server Software:        Cherokee
Server Hostname:        leemelo.com
Server Port:            80

Document Path:          /feeds/
Document Length:        13803 bytes

Concurrency Level:      50
Time taken for tests:   2.247276 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      2787200 bytes
HTML transferred:       2760600 bytes
Requests per second:    89.00 [#/sec] (mean)
Time per request:       561.819 [ms] (mean)
Time per request:       11.236 [ms] (mean, across all concurrent requests)
Transfer rate:          1210.80 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:    14  499 158.8    527     825
Waiting:       13  497 159.0    523     825
Total:         15  499 158.7    527     825

Percentage of the requests served within a certain time (ms)
  50%    527
  66%    559
  75%    578
  80%    600
  90%    667
  95%    725
  98%    769
  99%    818
 100%    825 (longest request)

Cherokee + Apache + Lighttpd Benchmark

This benchmark was performed by Brian Rosner with Cherokee 0.6.0 beta2.

Software

Hardware

Background

I installed a fresh installation of Debian on the server hardware. Right after you login you will need to get sudo to perform root commands from your account:

su
apt-get install sudo

Then add yourself to the /etc/sudoers file by running visudo and adding yourself in the user section. I just followed the root entry as this does not need to be a very secure server since it will not be running publicly. Now make sure you get back to your account and do:

sudo apt-get install gcc make automake autoconf libtool
mkdir src ; cd src
sudo mkdir /usr/local/cherokee
sudo mkdir /usr/local/lighttpd

The installed version of gcc is 4.1.2

Cherokee Setup Details

The following is what I executed to build Cherokee:

wget http://www.cherokee-project.com/download/0.6/0.6.0/cherokee-0.6.0b863.tar.gz
tar zxvf cherokee-0.6.0b863.tar.gz
cd cherokee-0.6.0b863
./configure --prefix=/usr/local/cherokee/0.6.0b863
make
sudo make install

Here is the configuration for cherokee:

server!port = 80
server!timeout = 60
server!keepalive = 1
server!keepalive_max_requests = 500
server!pid_file = /var/run/cherokee.pid
server!server_tokens = full
server!encoder!gzip!allow = html,html,txt
server!panic_action = /usr/local/cherokee/0.6.0b863/bin/cherokee-panic
server!mime_files = /usr/local/cherokee/0.6.0b863/etc/cherokee/mime.types

vserver!default!document_root = /usr/local/cherokee/0.6.0b863/var/www
vserver!default!directory_index = index.html

vserver!default!directory!/!handler = common
vserver!default!directory!/!handler!iocache = 1
vserver!default!directory!/!priority = 1

To run the web server I used:

cd /usr/local/cherokee/0.6.0b863
sudo sbin/cherokee -C etc/cherokee/cherokee.conf

Apache Setup Details

The following is what I executed to build Apache:

wget http://apache.oregonstate.edu/httpd/httpd-2.0.59.tar.gz
tar zxvf httpd-2.0.59.tar.gz
cd httpd-2.0.59
./configure --prefix=/usr/local/apache/2.0.59
make
sudo make install

I used the supplied highperformance.conf configuration file. I started the server with:

cd /usr/local/apache/2.0.59
sudo bin/httpd -k start -f conf/highperformance.conf

The server ran using prefork.

Lighttpd Setup Details

The following is what I executed to build lighttpd:

wget http://www.lighttpd.net/download/lighttpd-1.4.16.tar.gz
tar zxvf lighttpd-1.4.16.tar.gz
cd lighttpd-1.4.16
./configure --prefix=/usr/local/lighttpd/1.4.16
make
sudo make install

The configuration I used looked like this:

server.modules = (
    "mod_access",
    "mod_accesslog"

)

server.document-root = "/var/www"

mimetype.assign = (
    ".html" => "text/html",
    ".txt" => "text/plain"

)

I started the server with:

cd /usr/local/lighttpd/1.4.16
sudo sbin/lighttpd -f sbin/lighttpd.conf

Benchmark

I will perform several different benchmarks on each webserver. This is to help gauge what type of performance each server can handle in the different conditions. Each test will have SSL turned on and turned off.

small static file test

large static file test

Results

I have included cherokee with both iocaching on and off. The out of the box setting is that iocache is turned on.

small static file test w/ keepalive

small static file test w/o keepalive

large static file test w/ keepalive

large static file test w/o keepalive

Conclusion

TODO: write something here

If you feel I need to supply any more detail about any part of this process, please let me know. I want this test to be as accurate as possible. I also would like to continue using this process to test future releases of each software and ultimately help improve them. I am a Cherokee developer, but if I notice anything that would help other webservers I am more than happy to let that community know.


Cherokee 0.5

Benchmark of Cherokee 0.5.4 under Windows, contributed to the main mailing list. Here is the link to the non abridged post.

Cherokee had one million static requests and one million scgi dynamic requests with two ab commands started at about the same time. More info follows:


The scgi performance was quite impressive. I'm not sure about the
details of Cherokee's scgi and fcgi implementation. In my testing, a
multi-threaded scgi back-end written in Python was much faster
handling concurrent requests than a single-threaded fcgi backend
written in a compiled language, when the number of concurrent requests
was more than 5. But dealing with continuous but non-concurrent
requests, the natively compiled fastcgi takes about 40% of the time of
what it takes the scgi Python app to handle a request. This tells me
that the Python scgi backend (web.py) is able to cope with pretty
heavy traffic, which will be a bit less than half of the ultimate
capacity that could be achieved by running a server pool of
fastcgi/scgi written in a compiled language. (I'm assuming the
overhead of fcgi and scgi are similar, or the difference ignorable.)

The test is done on a single-CPU vmware guest OS running on a powerful
core 2 dual host. It was taking most CPU time of a core during the
test. No other vms or heavy tasks were run during the tests.

C:\Internet>ab -n 1000000 -c 1 http://localhost/image/google.html

Server Software:        Cherokee/0.5.4
Server Hostname:        localhost
Server Port:            80

Document Path:          /image/static.html
Document Length:        67859 bytes

Concurrency Level:      1
Time taken for tests:   6012.703125 seconds
Complete requests:      1000000
Failed requests:        5
   (Connect: 5, Length: 0, Exceptions: 0)
Write errors:           0
Total transferred:      -681476736 bytes
HTML transferred:       -860476736 bytes
Requests per second:    166.31 [#/sec] (mean)
Time per request:       6.013 [ms] (mean)
Time per request:       6.013 [ms] (mean, across all concurrent requests)
Transfer rate:          -110.68 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1  12.0      0    3015
Processing:     0    2   6.1      0     203
Waiting:        0    0   3.0      0     156
Total:          0    4  13.2      0    3046

Percentage of the requests served within a certain time (ms)
  50%      0
  66%      0
  75%     15
  80%     15
  90%     15
  95%     15
  98%     15
  99%     15
 100%   3046 (longest request)




C:\Internet>ab -n 1000000 -c 1 http://localhost/s/scgi/

Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests


Server Software:        Cherokee/0.5.4
Server Hostname:        localhost
Server Port:            80

Document Path:          /s/scgi/
Document Length:        693 bytes

Concurrency Level:      1
Time taken for tests:   8875.62500 seconds
Complete requests:      1000000
Failed requests:        5
   (Connect: 5, Length: 0, Exceptions: 0)
Write errors:           0
Total transferred:      803000000 bytes
HTML transferred:       693000000 bytes
Requests per second:    112.68 [#/sec] (mean)
Time per request:       8.875 [ms] (mean)
Time per request:       8.875 [ms] (mean, across all concurrent requests)
Transfer rate:          88.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   6.9      0    2984
Processing:     0    8   8.1     15     281
Waiting:        0    7   8.0      0     281
Total:          0    8  10.5     15    3031

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     15
  75%     15
  80%     15
  90%     15
  95%     15
  98%     15
  99%     31
 100%   3031 (longest request)

Other 0.5.4 benchmarks:

Older benchmarks