Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Nginx, the little Russian web server taking on the giants (pingdom.com)
318 points by yannis on Feb 24, 2010 | hide | past | favorite | 109 comments


Nginx runs all my Rails sites and will forever. If you haven't tried it yet, I can't say enough good things about it. It never breaks. It has just absurdly good memory consumption, which is clutch when you're trying to run your site on a memory heavy platform like Rails on a VPS which is very memory constrained.

(By comparison, Apache is quite the memory hog and I still haven't figured out how to say the magic words to get it to not effectively crash my blog and every other site on the server if I burst to 10,000 visitors in an hour. That is not supposed to be a big number. Apache has 500 MB to play with and still can't keep up.)

I also find, and this might just be a matter of taste, that the configuration makes more sense to me than Apache configuration does. This is funny because Apache configuration is obsessively well-documented and Nginx configuration is not.

Additionally, some easy-to-use features cover weak points in typical Rails (&etc) deployment scenarios. The big one for me is file serving, since my website is essentially one big PDF printing press. The simplest level (works for me, won't work for Facebook) is just having the file anywhere accessible on the disk and having the application put a special header on the response saying "Hey, Nginx: give them this path.", then terminating Rails' involvement. That frees up your Mongrel to start doing hard work again and greatly, greatly, GREATLY decreases the resources you need to stream your 5 MB PDF, 20 MB executable, etc to the user.

So it scales down, but does it scale up? Ooooooooh yeah. Impressively so. See the tales of Wordpress deployment, where not a whole lot of Nginx gets hit with a year's worth of my traffic every couple of seconds and still keeps on trucking.


You can upgrade the nginx binary while in flight. I've put the last 2 upgrades online in that manner. See http://pastebin.com/32UX6UQ2 for howto.


I thought Apache can also reload the configuration without dropping connections via graceful restarts?


Yeah, silvestrov is talking about "upgrading the binary" here.


ouch, I didn't know that one. Only plain restart.


Load balancers FTW.


So, is your preferred config still nginx + mongrels? Have you experimented with nginx + passenger or nginx + unicorn?


I use nginx+passenger and love the heck out of it. Trivial to set up, blazing fast, rock solid, and easy to administrate. I've switched away from Apache for everything except my dev server, and haven't looked back.


I experimented with Nginx + passenger and had little success in the time I had budgeted that weekend (almost certainly due to my own failings). That is my max geekout budget. After that I have to have a reason to rip out stuff and I've got no compelling reason to rip out Mongrel (nota bene: I typically deploy only one or two Rails applications per VPS, with the expectation that they'll essentially monopolize resource usage. If my deployments resembled that of a shared host who could have ~600 forgotten Build A Blog In 15 Minutes apps sitting around waiting for someone to access them again, I'd have figured out Passenger by now or paid someone to figure it out for me.)


How long ago did you try it? I think I started using passenger in the past....3 months? The version of install-passenger-nginx-module I used would compile your nginx for you, and set up the configuration. You just have to change the path to your public directory.


I found the main benefit of Passenger in a single-app setting is (much) easier initial setup.

Give it a try next time you set up a server. It'll save you about 30 minutes to an hour of screwing around with mongrel cluster configs and nginx proxying.


Passenger is worth figuring out, especially if you plan to do more Rack apps in the future. Forget the performance. It's easier to set up (at least, the second time) and it's easier to manage.


I've been using passenger + nginx very happily for a few months now. I'd highly recommend giving it another shot.


I'm wondering how often you have to restart your Mongrel processes? Seems Mongrel loves to bloat.


this sums up my experience with nginx. I have fallen in love with it :)


We've been using nginx at engine yard for 4 years now and I can say that it is the most solid peice of software out of the hundreds of open source componenets we run. We have close to 15k nginx dEmons running if not more last I counted and it accounts for 0.001% of production issues/problems.

Can't say enough good things about this peice of software. It just works and it's smoking fast and very resource friendly. Thumbs up all around


Ezra, you deserve a lot of the credit for the growth of Nginx. Your evangelism has done nothing short of catapulting its exposure in the community. So, thank you.


Thank you, I just looked back in time and it seems I started playing with nginx in 2006. Here was my first blog post whee I figured out how to run rails with it.

http://brainspl.at/articles/2006/08/23/nginx-my-new-favorite...

that config file lives in infamy on many thousands of vps's across the land ;)


Nginx is incredible. It's my second favorite piece of software (haproxy wins by a hair). At justin.tv we serve tens of billions of requests per month using nginx, and it uses so few system resources that we can run our CPU-heavy caching engine on the same servers.

Take a look at the source sometime. It's kind of fun to see an HTTP parser written like, "if (ngx_str3_cmp(m, 'G', 'E', 'T', ' ')) { r->method = NGX_HTTP_GET;"


I've absolutely loved patching and working on modules for nginx source code. Partially I suspect because it's so homogeneous. It's nice and modular and succinct - the optimizations don't obfuscate the code. As others have pointed out, responding to http requests is not rocket science, and digging into nginx reminds you that responding to a simple problem simply tends to yield pretty good reliability and performance.


Good to hear you would recommend Nginx. Would you mind expanding on how you use Nginx and haproxy together ? Do you front haproxy with Nginx or vice-versa ?


nginx front end -> haproxy -> caching engine -> haproxy -> app instances (multiply this stack N times)

haproxy's HTTP feature set is comparatively limited and we simply have too much traffic to put one machine in front of a bunch of web servers.


Duck Duck Go uses nginx. I evaluated all the alternatives pretty heavily, and it was the clear winner at the time (2 years ago). I currently use the memached plugin, which is great. I've also used its embedded Perl feature (though not currently).

Speaking of good Web servers, I've heard good things about Yaws lately. Anyone have any real world experience with it? This is the only seemingly solid comparison I've fond: http://www.planeterlang.org/en/planet/article/Nginx_vs_Yaws_...


Are you the duckduckgo founder?

I just wanted to say that I absolutely love your search engine. Really really good job on that.


I've been touting nginx to anyone who will listen here and elsewhere for 2+ years. It just never breaks. Billions and billions of requests, no problem. Spikes up to 500 Mbps, no problem. DOS attacks, misconfigurations, exotic in-a-pinch config changes (think: had to throw in a quick 100K URL map via the hash system), no problem. And the relatively small servers we run it on just putt away nearly idle. It's just too good.


    Pingdom: Where do you think nginx will be in 5 years?

    Sysoev: I really have no idea.
Although this statement sounded negative at first, it is actually brilliant. Rather than defining a cast-in-stone development plan, focus on what the market is going to be asking from you as you go along and code it.


Well, nginx started because Apache devs didn't want to address the issue that arised when lots of users with slow connections were accessing the site. Anyone else remember the Slowloris HTTP DoS - ngingx is basically immune to it...

As Sysoev was working for one of the Russia's biggest portals that apache couldn't handle very well.. So he wrote a server that did one thing very well - waits until client submits their request and then serves this request as fast as possible. And he did it well :)

Slowloris HTTP DoS - http://ha.ckers.org/slowloris/


Nginx got mentioned in printed books, mostly Ruby on Rails related.

I'm proud to say I contributed to this. From RailsSpace (2007), p. 506:

  Nowadays, it seems that many of the cool kids have switched
  to a webserver called Nginx, used on its own or as a proxy
  server. Since much of its documentation is in Russian,
  Nginx (pronounced "engine X") is relatively obscure, but
  we've heard great things about it, and it's currently being
  used by several prominent Rails hosting companies.
Everything in the quote is still true---except for the "obscure" part. :-)


I would disagree. Much of the documentation has been translated to English, with miscellaneous bits of information also available through sites such as StackOverflow and ServerFault.

That said, compliments on spotting a solid piece of software from a mile away.


Oops, you're right, two things have changed. There is a lot of English documentation now, too. My bad.


Coming up next are [...] probably new embedded languages: Javascript or Lua.

This is interesting. On Sysoev's personal website, there is an article "Why Google V8 is not suitable for embedding into a server yet"(Russian) http://sysoev.ru/prog/v8.html

Basically, he's saying that V8 was developed with Google Chrome in mind, so it's not an easy task to embed it with any other software. The main point is, V8 can't handle memory allocation errors - it just crashes the process, which is suitable for Google Chrome but not for a server.


I feel like the other point here is that writing a webserver isn't rocket science. If a webserver is very important to you, and nothing freely available really fits your use case well, just write your own.


Hmm... if you are good at epoll/kqueue etc and know about the various I/O models supported by Linux.

I think it takes time to gain that expertise.


If you don't have the time for that, try node.js - it handles all the epoll/kqueue for you, letting you program in high-level asynchronous javascript.


I beg to differ. A real-life scalable and modular I/O engine server is very tricky just to design.

nginx's code is amazing, even being barely undocumented.


+1 for NGINX + PHP-FPM + XCache + MySQL as a replacement for the LAMP stack - significantly decreased my web server's utilization of both CPU and Memory...


Can you detail this configuration? How easy/hard is it to setup this stack and then later maintain it? Plus, how much improvement did you actually get will be an interesting piece of info.


It's gotten a lot easier recently. I believe I installed PHP-FPM through aptitude, and nginx comes from that too. Compiling a newer version yourself isn't that hard. However maybe 2 months ago I couldn't say the same.

EDIT: I had to add dotdeb repo for php-fpm.


Yup, researched more and found this excellent Linode article

http://library.linode.com/web-servers/nginx/php-fastcgi-ubun...

Also, unrelated, but I see most arguments in favor of nginx say that it is excellent at serving _static_ files. Since my application serves mostly dynamic content, what do you think can be performance benefits?

EDIT: This article is fantastic too http://interfacelab.com/nginx-php-fpm-apc-awesome/


Well if you don't run your app as CGI then there might be a difference. For example using mod_php vs fastcgi or fpm (from what I hear mod_php is faster than fastcgi).

And if you host your static files on a CDN that's even less reason to use nginx.

Here's some benchmarks: http://blog.a2o.si/2009/06/24/apache-mod_php-compared-to-ngi...

It shows that if you just run PHP, mod_php results in better performance. So, many people who also need to serve static content use nginx for static, and then proxy PHP requests to apache (though this seems like it would defeat the purpose of needing apache).

Of course this all becomes moot if you consider that when you get to these points of performance demand you'll probably take a look at HipHop (assuming you use PHP) and compile your PHP+Web server into a single daemon.

EDIT: By the way, that linode article uses spawn-fcgi, not php-fpm. php-fpm is in the dotdeb repository and you have to add that to your sources.list.


  from what I hear mod_php is faster than fastcgi
Those benchmarks certainly back it up. Nginx in front of Apache seems like the best approach. I would like to see an optimization guide for setting up Apache to process PHP via mod_php. By comparison, I always found optimizing nginx to be far more straightforward than optimizing Apache.

On a sidenote, does it make sense to use HipHop in conjunction with xcache?

Here's what I'm thinking:

  nginx > static files
  nginx > php > apache + mod_php > xcache > HipHop


HipHop will completely invalidate your need for Xcache as you now have an executable instead of php. You can probably get away with nginx for static and proxy it to HipHop'd php for your php. But that's still overkill in most situations.

The nginx for static and php-fpm (which runs php as a fcgi) will get you very very far. Wordpress.com for example uses a similar setup (with a hell of a lot of caching in between).

Most of my apps aren't bound by php cpu time, I'd only use hiphop to play with personally. =)


Proxying to Apache for dynamic requests is still a win if you let nginx buffer the response. This local transfer is fast, which frees the apache process, and all the memory it uses, to serve the next dynamic request while nginix takes care of emptying the buffered data to the "slow" client. At the same time, you get to tap the vast knowlwge base for deploying php apps on apache.


Thanks, I wrote the interfacelab article.

We (at the time I was the CTO for massify.com) evaluated a lot of different configurations and nginx+php-fpm+apc was about the fastest we could get the site going.

Glad the article was useful for you.


on the maintenance side - I find NGINX conf files to be substantially easier to work with than Apache's - check out the demo conf at the end of this article for example: http://www.linuxjournal.com/article/10108 .

And setup was pretty easy, as most components are available from the package manner of your choice - http://www.newmediaist.com/n/installing-nginx-mysql-php-fpm-...


I love nginx, but one thing that I wish nginx could do is be able to enable/disable modules without having to recompile. It's annoying having to recompile nginx whenever a new version of passenger is released.


I agree with you there. Nginx should make it easier to automate this by having a link to the latest version like nginx.org/download/latest.tgz

Fortunately, nginx allows you to upgrade to a new binary on the fly.

http://wiki.nginx.org/NginxCommandLine#Upgrading_To_a_New_Bi...


Here's the script I've been using to install the latest version. It was kind of quickly hacked together, and the symlink stuff near the end breaks occasionally, so if anyone's going to use this, you might want to read it over first.

http://gist.github.com/313430


It's annoying, but I'd imagine there would be a performance penalty for having dynamically loadable modules. I'd rather keep the performance, and just have to recompile.


I suspect that a lot of that is performance-oriented. By compiling modules into the binary, I suspect you can get far superior performance out of it than you could with hot-loaded modules.


Calling dynamically loaded libraries is very fast, no more than a few nanoseconds per message that passes between the server and a module. It is no worse than the dynamically-linked C standard library we use so heavily.

Development effort is probably the real reason. It takes a fair amount of planning to design a table-driven module loader and indirection layer. Indirection with raw pointers costs brain power. (And do not even think about the reference counting hell of a dynamically unloadable module.)

Edit: And think about what happens when you upgrade a Django or Rails plug-in: it generally gets recompiled and what amounts to relinked. The difference is that the language system itself hides the work, while nginx uses explicit build tools.


Given that you can hot-swap the binary you could just write a bash script to enable or disable the modules you want and swap out the binary when it finishes compiling your changes.


Also check out Cherokee - http://www.cherokee-project.com/ - has a lot of similar features as nginx (small and fast), but also has a saner development model, public SCM, a bug tracker (!!!) and a friendlier dev team.

Among the most famous sites using Cherokee are the (recently hyped) chatroulette.com and Lawrence Lessig's web properties.


I find that cherokee and lighttpd is a pain in the butt when it comes to getting ssl working, all kinds of weird problems. It's dead easy with apache. How's nginx and ssl?


Pretty easy. Set up a block to accept connections on port 443, put 3 or four lines in the config pointing to your certificate, you're done.


Coming up next are backend interactions and cache improvements, refactoring of the rewrite module, and probably new embedded languages: Javascript or Lua.

I really hope he includes lua and javascript. Both would be cutting edge (Javascript server side is still pretty new) and Lua which should be used more. Kepler Project (http://www.keplerproject.org/) is pretty good but Lua gets no love, this could change things big time for Lua.


I wouldn't call server-side JavaScript "new" as such - Netscape were experimenting with it in 1996: http://en.wikipedia.org/wiki/Server-side_JavaScript


True, but in terms of people using it in production and some of the faster JS engines like V8, Tamarin, Spidermonkey, Rhino etc it is having a resurgence now that it is getting to fast enough.


Lua support inside of Lighttpd via mod_magnet is quite powerful for rewrites. Curious if there is a nginx equivalent.


here is small rant about v8 in nginx by Igor: http://sysoev.ru/prog/v8.html

It's in russian unfortunately... Probably google translate will help? In short - article says that V8 is not ready to be embedded in servers because of certain shortcomings.


I highly recommend Nginx. Not only does it use less resources than Apache, it is actually easier to use than Apache and Lighttpd. I found the configuration file format to be very easy to learn.

The only feature I miss from Apache is being able to use .htaccess.


I generally don't miss .htaccess

.htaccess made sense in the world of spaghetti code CGI/PHP scripts running on shared servers, in the world of app frameworks like Rails and Django that stuff (redirection, authentication, etc.) is better handled in the application.

The only cases .htaccess is useful in modern app development is for requests for static assets you don't want routed through the app (images, javascript, etc). Say you want to change MIME types of perhaps the content-disposition. But even in those cases, usually that should be documented as something to enable in the global server config, for two reasons: 1.) .htaccess needs to be checked each request for changes, slowing down your server 2.) you can't just assume .htaccess works, so the administrator needs to be aware of whats going on, in which case they may as well just put it in the global config. Unless your own a shared host like Dreamhost, in which case, yes, .htaccess is very useful.


nginx does support rewrite functionality with NginxHttpRewriteModule - http://wiki.nginx.org/NginxHttpRewriteModule

You can also setup nginx for Basic Authentication with NginxHttpAuthBasicModule - http://wiki.nginx.org/NginxHttpAuthBasicModule


afaik there is not htaccess support in nginx, is there?


Anyone written a plugin for nginx? I want to write a nginx -> redis connector for a project but haven't dug into the documentation.


Emiller's Guide to Nginx Module Development: http://emiller.info/nginx-modules-guide.html

Emiller's Advanced Topics In Nginx Module Development: http://www.evanmiller.org/nginx-modules-guide-advanced.html


There already exists an nginx module that talks to redis, it just does basic gets and doesn't support the entire redis protocol but it's a Start. Sorry don't have a link handy and I'm on my iPhone, a kittle google juice will find it for you.


Evan Miller's guide (already linked above) is great. But be prepared to dig into the Nginx code. Most things aren't documented, however, at least in my opinion, it has some of the cleanest large scale C code around. So, don't be scared to dig in.


Never used it, but there seems to be a module for doing so - http://wiki.nginx.org/Nginx3rdPartyModules#HTTP_Redis_Module


First thing I'd check out is the memcached module http://wiki.nginx.org/NginxHttpMemcachedModule


Would be a cool way to get Redis asynchronously serving requests for Tornado.


Crazy Russian hackers: is there nothing they can't do?


given enough time, you can do just about anything, and I suspect that is what's happening.

(this is especially true of software, where you don't need money- only time)


by the way, I just realized this could be interpreted wrong- I don't mean to disparage crazy russian hackers. It just seems like a feasible explanation for the number and magnitude of cool or impressive things I've seen come out of russia.

Ya know, Occam's razor and all.


Yes: publish software that does not include a trojan horse.


The author Nginx, Igor Sysoev, mentioned lighttpd as the nearest competitor to Nginx. I don't really keep up with webservers, what is the story behind lighttpd stagnating vs Nginx growing in usage?


I don't know about anyone else but I used to use lighty and followed the path I think most people would: Learning Apache, as it's a default, then using something faster to serve static files and proxy to Apache for content (Lighty, briefly), then experimenting with proxying directly to code with things like scgi, etc.

I was at this point, playing with Lighty as an alternative, when nginx first starting poking its head about.

After trying one installation of it, it was so much quicker and smoother that I basically instantly ditched any ideas of bothering with much else. Then you start running sites with any real traffic, where it's more stable than anything I've ever seen, with no real effort and it makes the amount of bs that goes into lighty look ridiculous.

So I guess "the story" is it targets the same niche, and it's better. Bonus being that the deeper you go or the heavier into that niche you are, the wider the margin is.


lighttpd had a memory leak that was around unfixed for a very long time. Googling couldn't tell me whether it was now fixed or not, but there are many references to it (take a look!). It did strike me as a problem that an essential bug like that wasn't looked at quickly, even if it was a little difficult to pin down.

Perhaps this is a bit unfair, but this is what led me to move over to nginx from lighttpd.


I've been using lighttpd for static files for a few years and never had any problems. It's faster and less resource intensive than Apache, and it's literally never crashed.


How well does nginx work with Java stuff? I'm setting up a new server, and want to run Jira and Confluence from port 80 (issues.site.com, wiki.site.com) and Atlassian has an article for getting this to work on Apache, but not nginx.

Does nginx work with any Java stuff?


Yes, it does work with Java appservers. See http://wiki.nginx.org/NginxJavaServers


Great, thank you for that. I think I know what I'll be playing around with tonight.


Foursquare runs nginx in front of Lift[1]. Not sure if they're using Jetty or some other servlet container, though.

[1] http://docs.google.com/present/view?id=dcbpz3ck_24f3v83ggz (slide 16)


We use Jetty (if anyone happens to care).

-harryh


Just switched from lighttpd a couple weeks ago. I've been convinced for a while now, but it's still nice to come here and see glowing reviews from Engine Yard and justin.tv.

Wrote a bit about my recreational CentOS install: http://todd.is/nginx-php-and-wordpress-migrating-from-lightt...


I've been using nginx for a long time now, and it's been great. Currently, I host my rails app combining nginx and unicorn with bluepill to manage the processes. I just don't trust passenger. Another specialty is that I use UNIX sockets instead of tcp ports for the reverse proxy, something unique to nginx/unicorn I think.


Why don't you trust Passenger? I'm severing about 6 million page views/day with it and it has been extremely reliable and easy to work with.


The most compelling use case I've seen where Passenger loses to Unicorn is rolling restarts. The biggest trust issue that I've seen is that of source editability - Unicorn and Mongrel are easier to debug and patch, while Passenger requires a commanding knowledge of Apache to fix.


Do you routinely edit the source code of your web server? Just curious since I've never needed to do that.


Phusion Passenger uses Unix sockets to communicate with backend processes since version 1.0.


nginx + passenger + REE for Ruby web apps is awesome. It's all I use these days.


It is awesome. I was using that until very recently, when I switched to Unicorn over passenger.


+1 for nginx/passenger/REE combo. Same stack I've been running all my ruby apps on.


I've written two "getting started with passenger + nginx" articles. One is for Ubuntu, one is for Mac OS X:

http://almosteffortless.com/2009/10/22/installing-varnish-wi...

http://almosteffortless.com/2009/09/16/passenger-with-nginx-...


I love Nginx. Though judging by the comments here, i'm not alone.

Nginx + Passenger + REE

FTW


The performance can't be argued with, but I find the config file format quite limiting compared to lighttpd's.


Really? I left lighttpd in disgust over it's nonsensical config files esp how they didn't work the way the docs claimed they did. After dicking with lighttpd to proxy the way I wanted for 1/2 a day I got nginx installed and configured in less than an hour.

nginx config files are logical


Logical, but restrictive. I still prefer nginx as software, but lighty's config syntax doesn't tie you up in quite so many knots if you're trying to do things out of the ordinary.


I wish something like webmin/virtualmin worked with nginx, I bet it would do wonders for it's uptake..


We're working on it.


Has anyone used nginx with cherrypy?


This is my exact approach for dozens of tiny internal / "glue layer" HTTP servers, all over the place, for a long time now.

It's brilliant. Almost effort-free and insanely fast, in most cases.

It offers a really cool path too, in nginx + Py -> nginx + Py/C -> nginx + C plugin, to grow from a quick throw-together prototype to something that will take as much load as you can make up with silly benchmarking tools, while development takes a sensible route.

Edit: As a cool more concrete example, I used this trick to build a very quick 'hardware access layer' for an embedded device when it was insisted that Flash be used for the UI. It was 99% Python but with nginx to serve static files and proxy the rest to Flash, and CherryPy as an access layer to a local SQLite DB for data, with Python C calls to proprietary hardware drivers for the device.

Sounds sloppy perhaps but for what it had to do and how well it runs it was incredibly quick and painless to put together.


Oh yes, lots--works fantastically well.

http://shoptalkapp.com is nginx -> haproxy -> (cherrypy/diesel)


HAProxy supports sophisticated balancing schemes, rule-based backend selection, etc.

I.e., if Host header is X, and Ip is Y, but no cookie was provided, then use pool... with this balancing scheme.

nginx's proxy setup out of the box is useful, but I wouldn't consider it on par with things like ZXTM or a Big IP when it comes to robust balancing/fallback patterns and flexible routing rules.

If there's a module that provides all that, I'm happy to hear about it--I haven't found it yet.


I'm curious why haproxy is in the mix. There's a couple of better balancers for nginx if that's why.


Why haproxy? I've always seen it as more of an incoming traffic choice, and actually use it in front of nginx clusters in some cases, this seems confusing.


If you're doing SSL work, something that does SSL decryption needs to be in front.

So I can't do my fancy HAProxy routing rules on HTTP requests HAProxy can't read--it would be reduced to a simple TCP-level balancer then.

Basically, nginx is there for ssl, gzip, caching (redis/memcache mod), and all those http-plugin-goodness things. Simple proxy directly to HAProxy on loopback, which specializes in load balancing, traffic routing, failover, etc. Then, finally, the application code on N nodes behind HAProxy.


I'm using this combination for the (low traffic) dynamic parts of my site. It seems to work fine.


Anyone using proxy_cache?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: