Tue 22 Aug 2006
High-Performance Ruby On Rails Setups Test: mongrel vs lighttpd vs nginx
Posted by Scoundrel under Admin-tips , Development , Networks ·
Because of not fully correct testing methodology, benchmark results are not fully correct. So, I decided to redo all tests. New benchmark results you can get in “Looking For Optimal Solution” series Summary post.
This week we have started one new project with Ruby on Rails as primary framework. My first task was to prepare runtime environment for it on one of our development servers. When I have tried to research how people doing it, I noted that there is no information about how to deploy rails application with nginx as frontend and what is performance of such solution. Before blindly make any decisions about future platform I’ve decided to make some performance tests of the some most popular rails web servers/frontends. Results of these tests you can find here with configuration samples for all software that I have used.
First of all I will describe hardware/software plaftorm of our development server. Our development server has following configuration:
- CPU: 4 x XEON CPUs
- Memory: 4 Gb of RAM
- OS: Debian GNU/Linux Testing with recent 2.6 kernel
Later I will describe every used configuration and apache benchmarking tool results. At the end of article you will be see aggregated results and performance comparison diagram for all solutions. All tests was performed with following command:
$ ab -c 100 -n 10000 http://127.0.0.1:PORT/
where PORT is specific port number that has was chosen for every test.
So, first described solution will be simple WEBrick server (web server written entirely on ruby and included in rails framework). To start it I have used following command:
$ ./script/server --port 8080 -d
Results of this test was really impressive for me. I thought, that Webrick should be really slow, but it shown non-zero results ;-). So, here are results:
- Web Server: WEBrick/1.3.1
- Time taken for tests: 51.490
- Time per request (mean): 514.896
- Time per request (mean, across all concurrent requests): 5.149
- Requests per second (mean): 194,21
- Transfer rate (Kbytes/sec): 1478,88
As you can see, this results may be acceptable for some small projects or for development, but for big frequently visited site we need something faster.
Second test was performed for Mongrel:
Mongrel is a fast HTTP library and server for Ruby that is intended for hosting Ruby web applications of any kind using plain HTTP rather than FastCGI or SCGI. It is framework agnostic and already supports Ruby On Rails, Og+Nitro, and Camping frameworks.
The easiest way to get started with Mongrel is to install it via RubyGems and then run a Ruby on Rails application. You can do this easily:
$ sudo gem install mongrel $ cd your_rails_app $ mongrel_rails start -d
Which runs Mongrel in the background. You can stop it with:
$ mongrel_rails stop
And you’re all set. There’s quite a few options you can set for the start command. Use the mongrel_rails start -h to see them all.
My Mongrel test was performed for single mongrel process started with simple:
$ mongrel_rails start -d --port 8081
Results are following:
- Web Server: Mongrel 0.3.13.3 (single process)
- Time taken for tests: 17.212
- Time per request (mean): 172.117
- Time per request (mean, across all concurrent requests): 1.721
- Requests per second (mean): 581,00
- Transfer rate (Kbytes/sec): 4398,28
As you can see here, Mongrel is really faster comparing to simple WEBrick server, but let’s see what other servers can show.
Third test was done with simple tcp balancer (pen) and 5 processes of Mongrel. Pen has been installed from debian testing repository, so installation was simple (apt-get install pen). Testing was performed on pen process started with following command line:
$ pen 8082 127.0.0.1:3000 \\
127.0.0.1:3001 \\
127.0.0.1:3002 \\
127.0.0.1:3003 \\
127.0.0.1:3004
In my test mongrel servers has been spawned by simple shell script written by me, but later I found mongrel-cluster - GemPlugin that wrappers the mongrel HTTP server and simplifies the deployment of webapps using a cluster of mongrel servers. So you can simply use it to make your setup process easier.
Results of this tests are better then in first test, but not as good as with single process:
- Web Server: Mongrel 0.3.13.3 (5 processes through Pen balancer)
- Time taken for tests: 19.864
- Time per request (mean): 198.642
- Time per request (mean, across all concurrent requests): 1.986
- Requests per second (mean): 503,42
- Transfer rate (Kbytes/sec): 3810,98
Next two test was performed in with two popular reverse-proxy servers: Nginx and Lighttpd and the same 5 Mongrel processes.
First tested server was Lighttpd, built with following commands:
# ./configure --prefix=/opt/lighttpd # make #make install
Folloiwing config file was used to start lighttpd:
server.modules = (
"mod_access",
"mod_proxy",
"mod_accesslog"
)
server.document-root = "/opt/lighttpd/www/"
server.errorlog = "/opt/lighttpd/logs/lighttpd.error.log"
index-file.names = ( "index.htm" )
server.tag = "lighttpd"
accesslog.filename = "/opt/lighttpd/logs/access.log"
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
server.port = 8083
server.pid-file = "/var/run/lighttpd.pid"
proxy.balance = "fair"
proxy.server = (
"/" =>
( ( "host" => "127.0.0.1", "port" => 3000 ),
( "host" => "127.0.0.1", "port" => 3001 ),
( "host" => "127.0.0.1", "port" => 3002 ),
( "host" => "127.0.0.1", "port" => 3003 ),
( "host" => "127.0.0.1", "port" => 3004 )
)
)
Results was really better, than in previous tests:
- Web Server: Lighttpd 1.4.11 (proxy for 5 Mongrel processes)
- Time taken for tests: 14.256
- Time per request (mean): 142.570
- Time per request (mean, across all concurrent requests): 1.426
- Requests per second (mean): 701,41
- Transfer rate (Kbytes/sec): 5321,53
Because of some strange problems authors of mongrel server do not suggest using lighttpd for proxying, but as for my it works well.
And last test was performed with nginx reverse-proxy and web server. I decided to test it after all other solutions because there are no documents about its performance and I want to show, how to setup it and check its performance with Ruby on Rails when I know all other results… So, I have built it with standard commands:
# ./configure --prefix=/opt/nginx # make # make install
and tested with following config file:
worker_processes 2;
error_log logs/error.log notice;
pid logs/nginx.pid;
events {
worker_connections 16384;
}
http {
include conf/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
upstream mongrel {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
server 127.0.0.1:3004;
}
server {
listen 8084;
server_name localhost;
access_log off;
location / {
proxy_pass http://mongrel;
}
}
}
Results of this test are really impressive, so I want to say “Thanks” to Igor Syosev for such great product!
- Web Server: nginx/0.3.60 (proxy for 5 Mongrel processes)
- Time taken for tests: 10.449
- Time per request (mean): 104.495
- Time per request (mean, across all concurrent requests): 1.045
- Requests per second (mean): 956.99
- Transfer rate (Kbytes/sec): 7267.27
Aggregated tests results you can see at following diagram:
So, I made my choice - I will use nginx to proxy requests to Mongrel cluster, because it is really flexible solution with great performance.
If you have some suggestions about additional tests or about results I described above, you can post your comments here and I will answer to all of you. Thanks and see you next time!
- HAProxy - The Reliable, High Performance TCP/HTTP Load Balancer
- Using Nginx, SSI and Memcache to Make Your Web Applications Faster
- Looking For Optimal Solution: Ruby On Rails and Mongrel
- Looking For Optimal Solution: Benchmark Results Summary and Findings
- 32bit VS 64bit - what do you use?
2006-08-22 at 6.01 am
Hello, Alex
Thanks for useful article. But I have a question: where is the apache (2.0 and 2.2 with mod_balancer)? Why you haven’t tested it?
2006-08-22 at 6.15 am
Ошибка в статье.
> Как и ожидалось, результаты оказались лучше, чем с одним процессом mongrel:
Это про pen. А насколько я вижу, результаты оказались хуже.
2006-08-22 at 6.35 am
Исправил. Вот что значит - тестить днем, а писать и переводить ночью.
2006-08-22 at 6.37 am
> Вот что значит - тестить днем, а писать и переводить ночью.
Бывает.
А почему не было тестов через FastCGI? Так что, медленнее, чем через HTTP?
2006-08-22 at 6.38 am
Сорри за такое количество комментов, еще хотелось узнать - а как это дело всё запускается? Писанный руками скрипт в init.d, или какой-то более удобный метод?
А то руками скрипты ломает писать.
2006-08-22 at 6.41 am
nginx - у меня где-то уже готовый срипт есть.
mongrel - через скрипт + mongrel-cluster.
2006-08-22 at 7.28 am
> WEBrick (веб-сервер, написанный полностью на ruby и включенный в состав rails framework)
WEBrick включен в дистрибутив ruby , в rails - только скрипт его запуска .
Присоединяюсь к вопросу - а где же apache ?
В общем и целом статья понравилась , спасибо.
2006-08-22 at 7.33 am
Насчет апача… Скажу честно - меня, как админа, видавшего апач много раз и в разных позах, сама мысль о том, что он как-то себя покажет в области проксирования сильно смущает… я попробовал поставить 2.2, но он тупо завалился при компиляции с синтакс еррором в области mod_load_balancer или как его там… дальше я не пробовал - НЕ ВЕРЮ! (с) и все тут…
Если общественность настоит - могу попробовать еще раз - для большей полноты картины
2006-08-22 at 7.38 am
Насчёт апача - +1. Не верю, что он может достичь скоростей lighttpd/nginx.
Но мой вопрос остался без ответа - почему не FastCGI, почему монгрел?
2006-08-22 at 7.46 am
А не пробовал увеличивать количество mongrel listners? Думаю для 4x Xeon оптимально будет 8 процессов + nginx.
2006-08-22 at 7.52 am
ошибка: “Вот и все, что необЗодимо.”
коммент потом можно удалить
2006-08-22 at 8.58 am
Кстати, померял скорость проксирования Apache 2.0/Mongrel и Apache 2.0/pen/Mongrel-cluster (5).
Как и ожидалось, результат почти одинаковый (второй вариант дал 5% рост производительности).
Ну же, Леха, когда будут результаты тестирования Apache 2.2 с load balancer’ом?
А вот на 2.2 посмотреть я не прочь
2006-08-22 at 9.11 am
Кстати, дебиановцы 2.2 уже включили в experimental, так что ждем его в скором времени в unstable
http://lists.debian.org/debian-apache/2006/08/msg00053.html
2006-08-22 at 9.38 am
2Alexander Solovyov:
Я попробовал запустить бенчмарк для FastCGI. Машинка слабенькая - 500 селерон, 512 RAM, но mongrel 1000 запросов отрабатывает относительно шустро (104.550197 seconds).
В общем эсперимент был сорван чрезвычайно низкой производительностью FastCGI. Я подождал полчаса, пока оно дошло до 300 реквестов, и на этом закончилось терпение
2006-08-22 at 9.52 am
> низкой производительностью FastCGI.
Хмм… Надо бы с django поэкспериментировать, может у неё что-то подобное тоже есть? :\
2006-08-22 at 12.36 pm
> В общем эсперимент был сорван чрезвычайно низкой производительностью FastCGI. Я подождал полчаса, пока оно дошло до 300 реквестов, и на этом закончилось терпение
Вы его готовить не умеете: у меня на cel-400 c apache1+FastCGI было около 10 req/s
2006-08-22 at 12.42 pm
Может забыли перебить в .htaccess редирект с dispatrch.cgi на dispatch.fcgi?
2006-08-22 at 2.15 pm
где фастцги, вопрошаю я, где?
2006-08-22 at 3.32 pm
What about pound [ http://apsis.ch/pound/ ]? We are using it with good results. Is the nginx better/faster than pound?
2006-08-22 at 3.35 pm
Notice: I’m going to review results of these tests and add some additional solutions like FastCGI with Lighttpd, Apache, nginx and pound server. So, stay tuned!
2006-08-22 at 4.42 pm
Thanks for doing the benchmarks. But I have one big question. What exactly are you testing here? Arew you just hitting the default welcome to rails page of a fresh new rails app? It seems that way to me. So I think your tests are flawed because they are measuring a static html file and not a dynamic rails request. You shou7ld at least set up a hello world controller/action that does at least a siumnple db select query to really test the performance of rails. I seriously doubt that you can get almost 1000 req/sec with a dynamic rails page. It is in the range of what you can expect for static pages but for dynamic pages with at least one db query you will more likely get somewhere around 90-130req/sec. Can you run your tests again against a real rails request? When you just test a staic file, rails does not even get invoked so you are not really testing rails at all.
2006-08-22 at 4.52 pm
2Ezra: Hmmm… I’ve tested on simple start page… Thanks for comment - I will redo all tests and will post results in next blog article.
2006-08-22 at 5.01 pm
Cool. I wasn’t aware of nginx before I saw your post so I am very interested in it. I downloaded it and I will play with it myself also. Thank you!
2006-08-22 at 5.10 pm
Alexander Borovsky: нет, не забыл. именно dispatcher.fcgi
2006-08-22 at 5.16 pm
Alexey- would you mind emailing me so we could have a discussion about nginx? I am writing a book about rails deployment and I am very excited to learn of this project. I would love to work with you to get the optimal setup for running rails with nginx/mongrel and nginx/fastcgi. Would you please contact me so we could discuss more? I think you should have my email already from the comment form. Thank you for your time.
2006-08-22 at 5.17 pm
hello
thanks for this post, i did not knew about nginx.
you might want to chechk out fcgi it is faster than fastcgi
i thought i would use mongrel or lightpd but apache + fcgi was faster (for http://sprinj.com at least)
2006-08-22 at 7.05 pm
Hi,
Just a typo notice:
The title says lihgttpd instead of lighttpd.
2006-08-22 at 11.15 pm
I have another question regarding nginx. Is there a way to set it up for use with rails so that it will first check for static files and then if it doesn not find a file it will invoke the proxy to the backend to get the request? This is how rails page caching works. So if an url like example.com/foo/bar was to be requested, nginx would look for /foo/bar.html and serve it directly if it exists but if not exist it would foreward the request to the proxy backend server? Maybe by using a 404 error handler or something? I would be very interested in gettign a nginx config that has nginx serving all static and page cached files and then forwarding any other requests to a cluster of mongrels via the proxy.
Thanks for mentioning nginx, I have been playiung with it today and I like it very much so far.
2006-08-23 at 12.40 am
2Ezra: yeah. You can create such setup for nginx. You can use rewrite module in following way:
server { root /path/to/your/public; location / { if (!-f $request_filename.html) { # your proxy configuration ... ... } rewrite (.*) $1.html last; } location ~ \.html { #dummy location for static files } }2006-08-23 at 12.55 am
Very cool Alexey. I think nginx is my new favorite front for rails apps. I’m not sure exactly what the dummy location for static files does? Can you explain? Also does this setup automatically serve images, js and css files as static if they are in the public dir of the rails app? Or do I need to add a location ~ .js and a location ~ .css, etc… ?
I appreciate your help with this.
2006-08-23 at 9.34 am
> I’m not sure exactly what the dummy location for static files does?
There you must define root for cached pages, like:
root /path/to/cache
> Also does this setup automatically serve images, js and css files
No, you must define location like this:
location ~* ^.+\.(jpg|jpeg|gif|css|js)$ {
root /path/to/static;
}
2006-08-23 at 2.56 pm
Как и все удивлен почему FastCGI не тестировался… Касаемо Lighttpd - reverse proxy у него несколько кривой не держит keep-alive что я думаю и является причиной тормозов в данном случае.
2006-08-23 at 5.55 pm
Хмм… Да, кстати, насчёт keep-alive, заметка на будущее тестирование: статические файлы надо бы сервить отдельно самим фронтендом, без бэк-ендов. Так и быстрее будет, и keep-alive влиять не будет.
2006-08-25 at 7.18 am
Hi,
great blog-entry
Please can you also add HAProxy to your tests
http://haproxy.1wt.eu/
— advertisment from homepage
.
.
HAProxy is a free, very fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP-based applications. It is particularly suited for web sites crawling under very high loads while needing persistence or Layer7 processing. Supporting tens of thousands of connections is clearly realistic with todays hardware. Its mode of operation makes its integration into existing architectures very easy and riskless, while still offering the possibility not to expose fragile web servers to the Net.
.
.
—
2006-08-25 at 8.21 am
[…] While I’ve been doing performance testing of different Ruby on Rails deployment schemes, I came across very interesting software - HAProxy. HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments. Indeed, it can : - route HTTP requests depending on statically assigned cookies ; - spread the load among several servers while assuring server persistence through the use of HTTP cookies ; - switch to backup servers in the event a main one fails ; - accept connections to special ports dedicated to service monitoring ; - stop accepting connections without breaking existing ones ; - add/modify/delete HTTP headers both ways ; - block requests matching a particular pattern ; […]
2006-08-26 at 4.58 pm
We would love to see LiteSpeed, http://www.litespeedtech.com. Our 2.2 in-addition to our Ruby LSAPI is one of the top performing platforms for Rail deployment.
2006-08-26 at 5.17 pm
2xing: I would be glad to add your software to next benchmark, but I can’t get trial version from your site… there is some error after trial download form… If you want, you can send me archive with trial version by email and I will test it.
2006-08-26 at 5.30 pm
2Scoundrel: We have fixed the trial form error. Please try to download the enterprise edition trial key once more. Thanks.
2006-08-26 at 6.19 pm
2xing: no luck…
But no mail… so, resend it to me manually, please.
2006-08-28 at 3.20 am
Wow I’ve got my license key for LiteSpeed! Will test it now…
2006-08-28 at 8.29 am
[…] Aftrer my previous post about high-performance RoR deployment methods, I’ve got lots of messages/emails/IM conversations about some errors in previous benchmarks and there were lots of suggestions about extending of tested software set and modifying testing methodology. So, that is why I decided to perform deep and wide performance testing for all deployment schemes I can find. In this article you can find description of testing methodology and, of course, benchmarks results. If you want to know details of specific software setup, take a look at articles in category “Ruby On Rails” to find all articles from “Looking for optimal Solution” series (I’ll post all of them in next few days). […]
2006-09-25 at 3.58 pm
[…] High-Performance Ruby On Rails Setups Test: mongrel vs lighttpd vs nginx […]
2006-10-04 at 2.30 am
[…] Obviously, this thing is powering 90k domains on the internet with benchmarks showing that it handles more requests per second (as high as 900+ on a single machine) than any other set up. I know that one benchmark doesn’t form substantial evidence but I think nginx will be something to pay attention to in the future (especially for shared hosts that can get taken down by rogue rails apps). […]
2006-12-20 at 6.58 pm
Another question concerning nginx. Since it has been installed I can not figure out how to set php.ini values such as upload_max_size. Is there a specific way to go about configuring these settings? There is no php.ini file in the path now being reported in phpinfo()
2006-12-20 at 7.22 pm
2Mark:
Configuration File (php.ini) Path => /etc/php5/cli/php.ini
Try such command and you’ll see where php tries to find its configs.
2007-02-12 at 5.22 pm
[…] “High-Performance Ruby On Rails Setups Test: mongrel vs lighttpd vs nginx” and many other nginx articles by Alexey N. Kovyrin […]
2007-03-22 at 12.31 pm
Thanks for your benchmarks! You can also use httperf to get speed tests.
2007-07-05 at 6.09 am
There’s a little difference in your setup, lighttpd has accesslogs on while nginx doesn’t. I guess that should make a bit of a difference, no?
2007-07-06 at 4.39 am
2Thomas: strange, nginx always has really flexible and pretty convenient logging system.
2007-09-14 at 6.17 am
Thomas means enabled logs on lighttpd may and probably will make things slower compared to nginx running without logging.
2007-09-19 at 3.38 am
Mongrel еще поддерживает фреймверк IOWA
2007-09-27 at 5.04 am
[…] http://blog.kovyrin.net/2006/08/22/high-performance-rails-nginx-lighttpd-mongrel/ […]
2007-11-07 at 6.30 am
[…] Rails 应用,有的评测性能已经超过 lighty。Nginx 能快速响应静态页面的请求,支持 […]
2007-12-06 at 6.58 pm
Aleksey,
I agree, I believe that Thomas meant that enabling the logs on the Lighttpd would make everything run slower than Nginx without the logs. But isn’t it obvious? If you want faster then you have to unable the logging features.
Jenn
2007-12-20 at 11.17 pm
[…] High-Performance Ruby On Rails Setups Test: mongrel vs lighttpd vs nginx :: Homo-Adminus Blog by Ale… (tags: rails performance mongrel lighttpd nginx rubyonrails ruby) […]
2008-01-14 at 7.20 am
[…] server has nginx installed there (frontend) and Rails-based application deployed like described in one of my previous posts or in other people’s posts on the net (nginx+mongrel). So, nginx proxies your request to one […]
2008-03-11 at 12.43 am
[…] EDIT: dimenticavo il riferimento a chi ha ispirato questo… post(?)… test(?)… studio(?)… va bhe: http://blog.kovyrin.net […]