Let’s put the nginx, Tornado and Apache and see who is the winner.

What to test:

A simple Hello World webpage.

How:

ab -n 10000 -c 300 http://myserver.ip

Test Environment:

OS: Ubuntu 9.10 (32-bit) / Linux 2.6.31
CPU: Pentium Celeron M 1.5 GHz
Ram: 512 MB
Apache: 2.2.12
PHP: 5.2.10
Python: 2.6
Tornado: 0.2
nginx: 0.6.13

Result:

Apache

Server Software:        Apache/2.2.12
Server Port:            80

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      300
Time taken for tests:   5.295 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2863146 bytes
HTML transferred:       130143 bytes
Requests per second:    1888.58 [#/sec] (mean)
Time per request:       158.850 [ms] (mean)
Time per request:       0.529 [ms] (mean, across all concurrent requests)
Transfer rate:          528.05 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8 151.0      0    3028
Processing:     0  122 602.0     48    5289
Waiting:        0  122 600.8     48    5284
Total:         10  130 622.1     49    5292

Percentage of the requests served within a certain time (ms)
  50%     49
  66%     50
  75%     50
  80%     51
  90%     53
  95%     63
  98%     68
  99%   5271
 100%   5292 (longest request)

nginx

Server Software:        nginx/0.6.13
Server Port:            8000

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      300
Time taken for tests:   3.172 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2230000 bytes
HTML transferred:       130000 bytes
Requests per second:    3152.12 [#/sec] (mean)
Time per request:       95.174 [ms] (mean)
Time per request:       0.317 [ms] (mean, across all concurrent requests)
Transfer rate:          686.45 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  68.3      0    3057
Processing:     0   70 359.1     27    3164
Waiting:        0   70 359.1     26    3164
Total:         10   72 365.6     27    3169

Percentage of the requests served within a certain time (ms)
  50%     27
  66%     27
  75%     27
  80%     27
  90%     28
  95%     29
  98%     32
  99%   3157
 100%   3169 (longest request)

Tornado Web:

Server Software:        TornadoServer/0.1
Server Port:            8888

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      300
Time taken for tests:   5.109 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1680000 bytes
HTML transferred:       120000 bytes
Requests per second:    1957.33 [#/sec] (mean)
Time per request:       153.270 [ms] (mean)
Time per request:       0.511 [ms] (mean, across all concurrent requests)
Transfer rate:          321.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   32 309.3      0    3035
Processing:    33  103  28.5    103     375
Waiting:       33  102  28.5    103     375
Total:         36  135 311.3    103    3154

Percentage of the requests served within a certain time (ms)
  50%    103
  66%    105
  75%    108
  80%    112
  90%    116
  95%    126
  98%    313
  99%   3121
 100%   3154 (longest request)

What do these numbers mean?

In a given time, if nginx and Tornado Web can handle 1.66 and 1.036 times more requests than Apache, respectively! In the other words, the server is more efficient and it can use the saved resource to do something else!

–Derrick

Our sponsors:

I just did a benchmark comparison on Tornado Web Server and Apache + PHP server. The result is pretty amazing.

What to test:

A simple Hello World application.

How:

ab -n 1000 -c 300 http://myserver.ip

Test Environment

OS: FreeBSD 7.1
CPU: Pentium III 933 MHz
Ram: 256 MB
PHP: 5.2.9
Python: 2.5.4
Tornado: 0.2

Result:

Apache + PHP:

Concurrency Level:      300
Time taken for tests:   3.515 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      255000 bytes
HTML transferred:       12000 bytes
Requests per second:    284.50 [#/sec] (mean)
Time per request:       1054.499 [ms] (mean)
Time per request:       3.515 [ms] (mean, across all concurrent requests)
Transfer rate:          70.85 [Kbytes/sec] received

Tornado Web Server:

Concurrency Level:      300
Time taken for tests:   1.907 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      168000 bytes
HTML transferred:       12000 bytes
Requests per second:    524.48 [#/sec] (mean)
Time per request:       571.993 [ms] (mean)
Time per request:       1.907 [ms] (mean, across all concurrent requests)
Transfer rate:          86.05 [Kbytes/sec] received

What do these numbers mean?

Tornado Web Server can handle 1.84 times more requests than Apache + PHP server in a given time!

–Derrick

Our sponsors:

Fedora Linux 12 is out today.

Here are the links to download Fedora 12:

  1. Download Fedora 12 64-Bit
  2. Download Fedora 12 32-Bit
  3. Download Fedora 12 PowerPC
  4. All versions

Suggestions:
I found that the downloading speed varies depends on which mirror you get. I suggest to test the download speed first, and re-try it (using a different mirror) if the speed is too slow.

For example, run the following command in terminal:

wget http://download.fedoraproject.org/pub/fedora/linux/releases/12/Fedora/x86_64/iso/Fedora-12-x86_64-DVD.iso

Which will show you the speed. Simply terminate the command and re-try it if the speed is too low.

Have fun with Fedora 12.

–Derrick

Our sponsors:

Recently we bought a Cisco RVS4000 4-port Gigabit Security Router and we noticed that the connection speed to the Internet was extremely slow. If we connected the server directly to the Internet (Without going through the Router), the download speed was around 80MBps, while the speed dropped down to 30 ~ 40MBps with the router with the default setting.

After disabling the IPS, the problem was gone!

Steps (IPS)- Required

  1. Go to the control panel (http://192.168.1.1)
  2. Go to the IPS tab
  3. Go to the Configuration Tab
  4. Disable the IPS function

Cisco RVS4000 4-port Gigabit Security Router - Slow Speed

Steps (Firewall) – Optional

  1. Go to the Firewall Tab
  2. Enable Firewall, DoS Protection and Block WAN Request
  3. Disable the rest

Cisco RVS4000 4-port Gigabit Security Router - Slow Speed

Looks like the IPS feature took too much resource from the router CPU.

–Derrick

Our sponsors:

I haven’t upgraded my Ruby On Rails and related Ruby gems for 5 months. One of the reasons is that Rails development team likes to break the backward compatibility, such as:

NameError: uninitialized constant ApplicationController

To avoid this kind of surprises, I tend to stick with a working, stable version.

Recently, I upgrade the entire Ruby On Rails family(2.3.2 -> 2.3.4), and surprisingly, my Ruby On Rails apps work perfectly fine! One exception is that the Mongrel server behaves a little bit slower than before. One way or the other, we need to use the load balancing technique to host the Rails App anyway. So it really doesn’t matter.

In case you want to try upgrading your Ruby Gems and other things:

Update the Ruby Gem Engine:

sudo gem update --system

Update other Ruby Gems:

sudo gem update

–Derrick

Our sponsors:

Recently I am playing the following technologies (toys):

  1. Tornado Web – Not sure how long will Apache + PHP last. Time to learn Python.
  2. Tokyo Cabinet & Tyrant – Another one of my long term plans to step away from SQL.
  3. PHP API for Tokyo Tyrant — I decide to write my own because I cannot find a good one.
  4. Moving my development platform from Windows to FreeBSD. My servers have been already on FreeBSD for many years. I think now is a good time to move my desktop systems to FreeBSD as well. Why not Linux? Oh Well…
  5. LUA – I may pick up Lua if time is permitted.

Looks like I will have a busy time other than shoveling the snow this Winter.

–Derrick

Our sponsors:

After upgrading to Snow Leopard (OS X) 10.6.2 from 10.6.1, I found that my system could not boot, no matter what option I chose at the boot prompt (-x, -v, -s etc). After trying for nearly half an hour, I was about to give up. Finally, I tried replacing the kernel and it rocked! I think I should share my solution here because I couldn’t find something like that on Google.

What I did:
Replacing the kernel of OS X 10.6.2 by OS X 10.6. You can find the old kernel from your backup (if you have), or from the Snow Leopard installation disk.

Steps:

  1. Grab your OS X 10.6 installation disk.
  2. Boot the system using the external DVD-Rom or USB Flash Drive.
  3. After booting to the installation screen, select your language and continue.
  4. Open Terminal
  5. Type the following:
cp /mach_kernel /Volumes/XXX/

where XXX is the name of your system directory. If you are not sure how to find it, you can try to run:

df

Warning(Side Effect):
When the system upgrades to OS X 10.6.2, it upgrades both the kernel (the brain) and the apps (the body) to 10.6.2. Now, we are downgrading the brain back to 10.6. It may cause unexpected behavior because the brain and the body are speaking different languages. You can think about the problem this way: The brain is speaking an old language while the body understands the new language only. Will they get along together? May be. Only Apple knows the answer.

So do it at your own risk.

Our sponsors: