I have been using Lighttpd for almost a year and Nginx for a month on my servers. I know that they were created to be massively scalable, solving the C10k problem. However their asynchronised-IO model and small memory foot-print also make them suitable as alternative HTTP servers for memory-limited VPS. Alternative = Anything but the current defacto Apache.
I will be writing more about Lighttpd and Nginx later during the year, but will try to use this post to draw some comparison between Nginx, the new darling of these light-weight web servers, and Lighttpd, many Web 2.0 developers’ all time favourite.
Lighttpd
I have been running Lighttpd (pronounced “lighty”) on my home servers and development boxes since the beginning of 2006. It is a great replacement for Apache if you have the whole box to yourself, i.e. you don’t need to worry about supporting .htaccess files that your users might use. Currently this website is hosted on lighttpd-1.4.13 on a Gentoo VPS.
Pros
- Light weight. Clean restart of 1.4.13 takes no more than 2Mb RSS on this 64bit VPS. It binds the port, drops the privilege and that’s it! A single process does all the tricks even when you have hundreds of concurrent connections. No more pre-fork MPM with mis-configured
MaxClientthat sends you to swap hell. - Speed. Very fast static file serving. Very fast FastCGI serving. Very fast proxy serving.
- Modules, and lots of them. Good comprehensive documentation as well. It even has SCGI for your Quixote apps.
- Mod_magnet. Wanna a scripting engine right inside your web server? Mod_magnet integrates Lua into lighttpd, so your World of Warcraft scripting skillz can be put into better use.
- Community. It has got a Blog, a Wiki/bug tracker and a forum. It is easy to find help when you need one.
Cons
- Stability (or lack of according to the RoR folks). I had quite a lot of issues using Lighttpd as proxy+HTTPS front-end for our Python stuff, but the same app runs fine with just lighttpd + proxy without HTTPS.
- Mod_rewrite (or again, lack of it). Built-in rewriting engine sucks, and porting Apache mod_rewrite rules over can be non-trivial sometimes. Update: Here’s an article I have written on Drupal clean URL on Nginx and Lighttpd, which looks at the URL rewrite options of these two web servers.
- Memory leak. The RSS of my lighty process grows by about 1.5Mb per day, but then I don’t have lots of traffic (less than 50k requests a day). At the end I just need to restart it once a week. Many people have far worse memory leaking issues I heard.
Nginx
I have been running Nginx (pronounced “engine X”) on my development box and two of my VPS’s since December 2006. It is Russian, fast and very configurable. I am currently using 0.5.5 for my sites, but don’t be deceived by its version number — it is very stable.
Pros
- Light weight. It is not as light weight as lighttpd when it clean-starts. At least two processes are needed — one master process running as root that binds to the port, and one or more worker processes that handle the actual requests. Around 7Mb RSS together on my 64bit VPS (and only 4.5Mb on 32bit VPS). Still beats Apache hands down.
- Fast. Some benchmarks have shown that Nginx has a slight edge over Lighttpd, but so far I haven’t been able to notice any. Again, much faster than Apache over static file serving or proxying, especially when you turn up the value of keep alive (more than 1 minute for example).
- Modules. There are many modules available on Nginx. Some very useful, and some are just plain weird. While lighttpd has Lua embedded, you can now also embed the whole Perl interpretor inside Nginx.
- Better Rewrite Module. A much better rewrite module than Lighttpd that supports complex conditions. Porting mod_rewrite rules from Apache is actually now feasible without touching the apps themselves.
- Stable and not leaking. Been running Nginx on a production site doing PHP-FastCGI, and have no issue what so ever.
Cons
- Lack of community. Where can I find help regarding Nginx? There’s only IRC as far as I know. And while the lead developer writes beautiful code, all documentation were initially in Russian which was a big stumbling block before the English docs came along.
- No CGI support. Oh well, maybe I am the only one who still hacks small CGI scripts. Apparently Nginx does not spawn CGI or FastCGI processes, which means you need to either (1) convert it into external-spawn FastCGI, or (2) proxy to another web server that does CGI.
- No simple virtual host support. Lighttpd has mod_simple_vhost and mod_evhost to let you quickly deploy lots of name-based virtual hosts. You can somehow do the same with using
$server_nameinrootand a wild-card inserver_name, but it’s still not as clean as lighttpd. At the end you will find Nginx configuration files much more verbose if you run lots of small sites off a single web server. - No X-sendfile support. I found Lighttpd’s X-sendfile support very useful when my scripts need to send back large files, and was disappointed to find out that Nginx does not have it. X-Accel-Redirect is different as it requires extra configuration on web server, which makes your web-app less portable.
Conclusion
I don’t think I am a suitable judge to say which one is better, as (1) I have only been running Nginx for a month, and (2) my level of traffic does not really stress test these high-performing web servers. At the moment I think I like Nginx better purely because it does not leak, and its rewrite module that enables me to run many off-the-shelf open source PHP apps with clean URL.
Again, I might change my mind in 3 months time when I find out more warts about Nginx. We will see.

Delicious
Digg
Reddit
Comments
Nice comparison. I was looking to dabble w/ Nginx more, but seems Lightty is still best for my needs.
Nginx has a mailing list where you will get an answer (from the author) within 24h. It also has X-Accel-Redirect which is similar to X-sendfile.
Tomislav — although you can achieve the same with X-Accel-Redirect, but I think their philosophy are different.
With X-sendfile, you can basically return any file on the local FS from your scripts, and no configuration is needed on the web server side. I think it is more flexible, but require smarter scripts to figure out where private data is.
With X-Accel-Redirect, the scripts and web server configuration are sharing that responsibility. Scripts tell the web server which file to return from that predefined location, and then web server can actually define the root of that location, abstracting from the scripts. I guess the idea is, you can just copy the scripts onto different deployment without modification, and you just need to configure web server properly.
However I found it is not often the case, as the scripts usually also need to know the absolute location of the files to return. For example I need to check the existence, size, geometry if it is an image file, etc. You might as well provide X-sendfile since scripts already know the absolute path to the files.
The embedded languages sound more novel than useful. As they say in the mod_magnet documentation:
Keep in mind that the magnet is executed in the core of lighty. EVERY long-running operation is blocking ALL connections in the server. You are warned. For time-consuming or blocking scripts use mod_fastcgi and friends.
So nothing CPU-intensive, and no database access. (The latter’s not a fundamental restriction - it’s possible to write a non-blocking one that returns to the server’s event loop while waiting for a response - but it’s difficult enough that probably no one will bother any time soon. Just use mod_fastcgi as they suggest.)
The memory leak sounds like a deal-breaker, but at the same time, it should be easy to fix.
Thanks Scott.
The same is said about Nginx’s embedded Perl module. You won’t expect to write any “application” that would block the whole web server for significant amount of time, but they are good replacement for otherwise lacking mod_rewrite support.
Did you tried what says here in the last comment?
http://trac.lighttpd.net/trac/ticket/758
You should test out LiteSpeed web server as well.
http://www.litespeedtech.com/
Have been using them since 2004 and they are top notch even with the free as in beer version.
Testing out Litespeed is certainly on my list of todo’s. Thanks for reminding! :)
I second the suggestion for Litespeed. I have a 256 MB VPS at slicehost, and Nginx + 2 Mongrel process w/Rails didn’t leave alot of memory for other things. I switched to Litespeed + Rails via LSAPI, and I found it uses alot less memory running the same number of ruby processes.
I’ve tested alot of front-ends like Apache, LightTPD, Nginx with different backends (Mongrel, FastCGI, SCGI) and Litespeed is the most memory efficient way I’ve found to run Rails.
Did you find any speed differences? I assume it uses least memory mostly because it replaces apache with a small exec — litespeed. Good for least mem used :)
I don’t know about nginx 0.5.5, but latest as-of-today (I think) 0.5.10 has pretty easy to use virtual server support. I don’t know how you missed it, you just have to define multiple server{} sections, and inside each of them use the appropiate listen/server_name directives. I’ve ported my 5 sites running on same server pretty easy, some even using https (but on a port different from 443, of course).
zap — yes the ”server” statement was there in 0.5.5. In fact I was surprised that how fast Nginx progressed over the last couple of weeks (I’m running 0.5.11 on two production sites now).
I am actually talking about “massive” virtual hosting, where you can add new virtual hosts without modifying the configuration file. Nice for a blog farm :)
For example, Lighttpd’s modsimplevhost or Apache’s modvhostalias.
I am actually talking about “massive” virtual hosting, where you can add new virtual hosts without modifying the configuration file. Nice for a blog farm :)
For “mass hosting” you just need in main config file
include vhosts/*.conf
and some “vhost.conf” files.
To make nginx reload config kill -HUP pid. In that configuration you can have as many vhosts as you want. It’s easy can be implemented an frontend like web-interface to generate those files.
nginx question. Do you know how to configure nginx to not serve up certain files. I tried for a while, but the only solution I could come up with was to use location and do a return a 403 when on a directory match. This however will break things like drupal with .css files in misc,modules and themes. I’m back on lighttpd till I figure this out.
Sorry not sure what you meant? Are you looking for functionality similar to X-send-file? Or looking for rewrite rules for Drupal? Can you give me an example?
Setup a drupal site using nginx and try to prevent a user from downloading the source of say http://www.example.com/modules/node/node.module . This would be a drupal rewrite rule.
I’m no pro by any stretch and learning more every day but wouldn’t the following rule work (modules directory for example)?
location /modules { allow 10.0.0.0/24; # my local network deny all; }
Actually scratch that earlier post, this might offer some assistance to get the brain juices flowing. Since I’m about to bring a dedicated drupal server online using nginx I thought you brought up a great point.
How about this:
For valid_referers use all ip addresses associated with that web server.
location /modules/ {
validreferers 10.0.0.10 10.0.0.11;
if ($invalidreferer) {
}
}
Here is what I ended up doing.
(there is a blackslash before the “.” after the rewrite.
I’ve just setup litespeed 3.2 on my new slicehost vps (finally getting around to setting this vps up!)
It works pretty well & I like the webadmin interface its awesome!
Had a bit of a tricky time getting PHP5 w/ lsapi going since its not in portage and I’d never compiled anything without before…
Not sure on how secure in a shared environment it would be since I use the same username for each site in under the same grouping. This means that even though they are separate the files have the same permissions… Under Apache2.2 I ran mpm-itk and every vhost ran as a different group:user and my assigned permissions on the files was like this - unix = znd - www user = znd:apache02 - www chmod = 660 + unix user = john + www = john:apache03 + www chmod = 660 - unix user = john - www user = john:apache04 - www chmod = 660
So as you can see each vhost couldn’t read anyone else’s files, just wasn’t possible :)
I just read that comment again and it doesn’t make sense (the last bit so here it is again)
Right so as can be seen clearly now same unix user account to access the files and change whatever - but different vhost userid:group so each vhost simply cant read any other files :)
I’m looking for a url re-write solution for Wordpress MU, where i can get both subdomains and directories fully under control. e.g. chicago.myspace.com and myspace.com/chicago-the-band
can one of the two solutions above accomplish that? I know with MU and Apache, I can only do one or the other.
Tomislav — although you can achieve the twin with X-Accel-Redirect, but I think their philosophy are different.
With X-sendfile, you can basically return any file on the local FS from your scripts, and no brand is needed on the web server tribesman. I think it is more flexible, but require smarter scripts to figure out where private data is.
With X-Accel-Redirect, the scripts and web server keynote are concord that responsibility. Scripts tell the web server which file to return from that prebaptized fix, and then web server can actually seal the root of that disposition, abstracting from the scripts. I guess the fantasy is, you can consistent come close the scripts onto different collation without modification, and you fair and square need to configure web server properly.
However I conceive it is not regularly the case, as the scripts by and large also need to the specifics the absolute alhomecroft of the files to return. For call to mind I need to bridle the existence, spaciousness, geometry if it is an definition file,
Performed quite aggressive test with MILLIONS of http queries and UNABLE to confirm memory leaks at least in lighttpd core itself + basic modules allowed.
My test machine (actually my destop) Configuration: AMD Athlon 64 3800+ x2, 1Gb RAM, etc. OS: Kubuntu x64 version 7.10 Server: lighttpd 1.4.18 (default version taken from repositories, seems to be current one) Enabled modules are: “modalias”, “modaccess”, “modstatus”, “modaccesslog”
What has been done?
1) I did measured memory consumption immediately after daemon startup. Not a completely fair since this is not a “cruiser mode” (no users served) but let’s be completely honest and fair, we will measure ALL memory eats.So here we go.All sizes are in Kb. VmSize: 45460 VmRss: 924
2) I’d performed 1 000 000 http requests, 500 in parallel. Using localhost for speed. I did used http_load tool (great tool to load servers from thttpd web site). File urls - contain just one URL - single file near 4.7Kb in size.
Command was the following:
3) Looking on eatten memory: VmSize 47036 VmRss 2692 Hey?Looks like memory leak? Really? Nope, wrong! Just entering “cruiser mode”. Some proof needed, yeah? Easily.
4) Re-running this command yet another 4 times.That is it. 4M http requests done.
5) Let’s look on memory, it’s all about RAM, right? VmSize 47036 VmRss 2692 Wow.There is still 2692Kb eatten on my x64 system and number is no longer increases, even after some extra 4M requests were served.So, this value is stable enough.
Repeated more and more.9M requests done,No change.Cool, yeah?So where are the leaks?And wtf I have to restart server?
P.S. I can assume some module may be flawed. Also looks like server can increase memory usage once this needed and not willing to give memory back.Still not a memleak though since this value is static and never grows and only depends on amount of simultaneous connections and file size to send.Yes, if you’ll do bigger files transfers in a millions, more memory can be wasted (I seen up to 48Mb VmSz and ~4Mb VmRss on 1 000 000 fetches of 9Mb file, 500 in parallel).However this is a peak value, it DOES NOT increases ever.You can re-execute millions requests again and again, nubmer will not increase.
What is handled at that URL? Static file? FastCGI? Proxy?
On my slicehost VPS, Lighttpd 1.4.18 on Gentoo grows around 4MB VmRSS every 100k requests (mix of static files + FastCGI). I haven’t had time to figure out the issue…
I’d used one simple static ~4.7Kb file for “fast” test as an URL, over 10 M requests were issued in total for this file without any proof of memleaks. Also attempted with 1M of downloads for bigger 9Mb file (only one launch with memory consuimption monitoring since this test takes some noticeable time). Still no memleaks. If you have better idea about files set you’re welcome. However please be aware that I do not have too many time for tests, that’s a hobby.Nothing more.At very most all reward I can have from it is filing bug report if memleak proven and using fixed version.Duh.Still pretty nice reward though.
Actually my test is very basic and just covers only core server functionality i.e. ability of server to handle HTTP requests on a quite loaded server without issues for himself.
Did not tested FastCGI so far as well as lots of other modules. This requires decent amount of time and it is not looks like I have enough of it right now. However in long term I will be glad to catch issue and file bug report.Or, better you can do this, too :)
You can do CGI, but you must do it through FastCGI. There’s a guide in the nginx wiki on how to do it. The script may need a few mods, but it works and it wouldn’t be difficult making it start on boot.
likely outdated by now, but there are plenty of good howtos out there to get nginx to do cgi/fastcgi:
I did it on lenny the other night from a fresh install; took about 20 mins. Great article btw, care to write an update since this is now +1 year old?
I never said that it cannot do FastCGI. What Nginx can’t do is spawning FastCGI processes within Nginx. Not that it is always a good thing, but I would like to see something like the FastCGI processes life time management in mod_fcgi for Apache…
And Nginx still can’t do CGI. There are plenty of CGI-only apps out there that do not want to be converted to FastCGI (for example, only executed a few times a day). But then it is easy for Nginx to proxy those CGI requests to a small webserver (boa, thttpd) just to serve CGI traffic.
It’s been over a year since this article was posted; it would be nice if we find up-to-date comparisons, including all the developments in lighty & nginx within the past year.
I’ve started a wiki to do just that: Lighttpd vs Nginx - WikiVS
Thanks David.
It looks like the article is old even if the comments are recent. But it would nice to hear how people compare Nginx, Lighttpd, and Litespeed. The last one seems to be the easiest to get running and administer with a web based tool. Does anyone have any experience servicing these machines on WHM/Cpanel servers?
is there any table overview to see what does the webservers have or not?
Nice comparsion. What is your opinion about Nginx now? I am really surprised that soup.io uses it, so it seems to be good!
The speed differences between Lighttpd and Nginx are minimal. In truth, both web servers do a good job if you set them up properly. What makes Nginx better is the active development community, the author’s attention to security and the flexible scripting language in the config file. This allows you to filter traffic on pattens you see in the log file and secure your server from malicious bots and bad clients.
Post new comment