I’ve been a satisfied Ruby on Rails developer for quite some time now.
Recently I’m considering using Rails again for a new website. But this
website has many visitors - 40k unique visitors per day (and about
200k page loads per day) - so I’m worried about performance and memory
I wrote a little test application - it has one controller, ‘Person’,
and one method, ‘test’. The method ‘test’ is not implemented, I only
put a file ‘test.rhtml’ in the ‘views/person’ folder. test.rhtml
contains the text “hello world”.
I started Rails as follows:
(output is redirected to /dev/null so that I won’t be testing the
performance of my terminal emulator)
Rails uses lighttpd as web server. I ran httperf as follows:
httperf --num-conn=100 --server=localhost --port=3000 --uri=/person/
test --timeout=5 --hog
And the result is alarmingly low: the request rate is only 15.5 per
For comparison, I also wrote a ‘hello world’ PHP script (test.php) -
the script doesn’t contain any PHP calls, only the text ‘hello world’:
httperf --num-conn=100 --server=localhost --port=80 --uri=/test.php –
Request rate: 1018.3 req/s (1.0 ms/req)
It seems rails is about 100 times slower. I can load balance the
website, but that costs money - lots of money. I don’t have that much
money. Am I doing something wrong, or is Rails really that slow?
I’ve also tried Mongrel instead of lighttpd, but there was no
performance increase. Speaking of Mongrel, why is it so popular? Why
is everybody moving away from lighttpd and toward Mongrel?
- Last time I checked, Mongrel can only process one request at the
same time. So suppose a Rails requests needs 5 seconds to complete,
then all other clients will have to wait 5 seconds as well. Lighttpd
seems to spawn a new Rails process if the current one hasn’t finished.
- I also read that people uses Apache (or lighttpd) as load balancer,
and proxies requests to several Mongrel instances. But doesn’t that
waste memory like mad? Each Mongrel process seems to need 31 MB at
startup (and this is for an empty ‘hello world’ Rails app). If you
have n Mongrel processes then you need at least n*31 MB of memory!
Almost no memory is shared because the Ruby parse tree is not shared
between Ruby instances, unlike native shared libraries.
Can someone provide me with the answer to these questions?