Apache or nginx?

  • Apache has long been the standard web server platform on Linux.  It is the "A" in LAMP.  When you set up a Linux based web server, for years it nearly went without saying that you would be using Apache.  To be sure Apache is a powerful choice and it is highly flexible and highly capable.

    However, Apache has some disadvantages, especially when it is used with the PHP module.

    Apache's process model is such that each connection uses a separate process.  (That assumes the Prefork MPM, which is virtually necessary when using the PHP module.)  Each process carries with it all the overhead of PHP and any other modules you may have loaded.  An Apache process might run a PHP script for one request, then serve a static request.  If the PHP has a memory leak (which does happen sometimes), the process continues to grow in size.  Also, when KeepAlive is enabled, which is usually recommended, that process stays alive for a few seconds after the connection, consuming a "slot" that another client might be able to use and helping the server to reach its MaxClients sooner.

    nginx is an alternative webserver that normally uses the Linux "epoll" API to process requests in a non-blocking mode.  What this means is that one single process can handle many simultaneous connections.  epoll is an efficient way to tell the single process which connection(s) it needs to deal with and which can wait.  nginx has a goal of solving the "C10k" problem - how to have 10,000 concurrent connections.

    This naturally goes hand in hand with php-fpm, the FastCGI Process Manager.  nginx does not itself have PHP built in.  When it receives a request for a PHP script, it makes a call out to php-fpm to run the script, which then returns the result to nginx, which returns it to the client.

    This all uses much less memory than a similar Apache+mod_php configuration.

    There are a couple more huge advantages of php-fpm over mod_php:

    - It uses different "pools", each of which can run as a separate Linux user.  This provides a simple and effective way of isolating web sites from each other (for example, if they are run by different customers who should not read each others' code) without the overhead or nastiness of suexec or suphp.

    - It has a slow log feature where it can dump a PHP stack trace of any script that has been running for greater than X seconds.  This can help diagnose slow code issues.

    php-fpm can be run with Apache, and in fact this allows you to take advantage of Apache's more efficient Worker MPM (or Event in Apache 2.4).  However, my experience is that configuring it in Apache is significantly more complex than configuring it in nginx, and even with Worker, it still is not quite as efficient with nginx.

    Disadvantages to moving to nginx - not many, but things to keep in mind:

    - It does not support .htaccess files.  I think this is a good thing personally as .htaccess files must be parsed by Apache for every request, which can cause significant overhead.

    - Configuration files need to be re-written.  If you have many complex site configurations, this could take some doing.  For simple cases it is not usually a big deal.

    I hope this is informative.  Let me know if you have any questions.

    Regards,

    Micah Yoder

    Linux support, RHCE

    Rackspace

  • Awesome breakdown between the two! I concur with the PHP performance over Apache. At one point in the past, I was running several vbulletin forums on a very low powered server with very limited resources.

    I was constantly tweaking Apache to try and reach just a tad more out of it. When I switched over to nginx, it was a night and day difference!

    Might I also suggest, another great http service to try out with similar results would be lighttpd. From my experience, it is a little more simple to configure yet does not have all of the bells and whistles of nginx out of the box. For example (at least last time I used it), load balancing, etc.

  • Great post Micah! The only thing that I can think to list under disadvantages is that since Apache has such a larger market share, it can be easier to find guides/tutorials/walkthroughs for Apache.

    - Josh

  • Long time Apache user here. I've never looked into nginx, so thanks for this post speaking to the pros and cons - I'll be looking into this.

    Charnell Lucich
    Community Engagement Manager
    charnell.lucich@rackspace.com

  • Indeed most tutorials assume Apache, so that could be considered another (slight) downside to nginx.

    Another one might be that it is not normally supported with your operating system.  If you use Red Hat Enterprise Linux for Red Hat's support, that might be an issue.  But nginx has commercial support also.

  • I hate to add to the negativelist, but another thing to think about when wanting to go to any non Apache web server is that there are many web apps out there that are natively coded for certain Apache features and might not play well without some tweaks to run with nginx.

  • Kevin - do you know of any specifically?  Typical PHP applications can work just fine with nginx, including all major CMSes that I know of.  If you're referring to apps that provide their own .htaccess files, which many do, then yes, converting them will take a bit of doing.  But those are usually optional.  And there are online recipes for most CMSes in nginx.

    I should also note that nginx can proxy to WSGI Python web apps with little trouble.

    Tomcat might be a bigger issue, but I believe there's a Tomcat connector for nginx also.

  • I've had great success increasing the capacity a Tomcat web application can handle just by putting nginx infront of it with a simple "proxy_pass" directive.  Throw in some static caching and this particular customer went from a couple hundred to a couple thousand concurrent users, with room to grow still.

    -----
    Andrew Regner, RHCE, CCNA
    Linux Systems Administrator
    Rackspace: The Open Cloud Company

  • Good post.  In my experience the contrast between the two heavily depends on what you're trying to do and how much work you want to put into it.  Nginx is shiny and new, and it's also easy to make it perform really well under load test conditions without a lot of configuration.  Apache's an old workhorse - broader feature (and legacy) support, but it takes more tweaking these days to make it feel anywhere near as zippy.

    You can use apache and mod_php with the worker MPM, for example - you just need to make very sure that your PHP modules are thread-safe.  You can also use apache with fastcgi for PHP.  And you can throw varnish in front of any web server to take a lot of the load off.

    The question for most users would be, why bother doing all that work if nginx can perform without as much configuration?

    Apache's main edge is for its application support (since there are still some, like cpanel, that require it) and for some features apache handles better than nginx (in the unlikely event I were maintaining a multi-user web server, for example, I'd want to do it with apache).  It's also good for learning how to admin a web server because of the large numbers of tutorials and books you can find for it.

  • Nice informative breakdown of the two.

    What about security? How do they compare?

    Reading posts about nginx, i was made aware of a particularly nasty one involving php : cnedelcu.blogspot.com/.../nginx-php-via-fastcgi-important.html

    ~ajoy~

  • Ajoy,

    Security in general - nginx should in theory be better, because it has a lot less cruft included by default.  Also nginx usually runs as the 'nginx' system user, which usually doesn't have access to much.  Apache + mod_php, of course, runs as 'apache' which often has write access to folders where PHP scripts are executed from.  I have not heard of a specific serious vulnerability in nginx itself yet.

    I have heard of the specific issue brought up in that article, and it mentions specific ways to mitigate the issue.  I personally recommend trying to restrict PHP execution to carefully selected directories that are known to contain code, which would hopefully exclude all directories writable by the php-fpm pool user.  Unfortunately some CMSes want to be able to write PHP files for template output so that doesn't always work.  If the fix_pathinfo fix doesn't work, the suggestion to exclude URIs that include a dot followed by a slash should mitigate it pretty reliably.

    In any case thanks for that link - anyone deploying nginx+php-fpm should absolutely read it.

    -- Micah