As we get higher and higher on the hosting stack, we really do need to start lending some importance to what our engineers are familiar with. As far as web server software goes, that includes some poking around with IIS, Apache Httpd, Apache Tomcat, and Nginx. A lack of experience in lighttpd, Node.js and some of the others precluded us from those. We needed to tweak the internals. That is difficult to do while learning a new product.
Since our operating system choice in part 2 of the series precludes the use of IIS and other Microsoft products, we are left with a choice between the two Apache products and Nginx.
I apologize from lumping the alternatives like Glassfish and WebLogic into this category. Despite one of our engineers really liking Java, we didn’t think it was a sound idea to invest in Java application hosting… Perhaps in the future we will open a branch and specialize in it, but for the time being we are looking to host PHP applications.
Our engineers have close to a decade of experience working with Apache Httpd. Apache Httpd was the most common web server on the internet years ago (it may still be). Literally everyone used it. It is stable, fairly secure, supports PHP, and has a massive amount of add on modules in varying states of development. It is a solid choice for any web server.
One of the most common configurations of Apache Httpd uses mod_php. This configuration allows seamless parsing of PHP scripts and serving of dynamic content. This ease comes at the cost of performance as Apache Httpd is forced to load mod_php into every thread/worker regardless of whether it is a PHP script or a static .jepg.
Nginx is a “newer” web server. We say “newer” because as we understand it’s been around since about 2002. It’s pretty trendy right now. Everyone that wants to seem cool, wants to switch from an Apache stack (LAMP) to an Nginx stack (LNMP..?). Nginx excels in simplicity and performance. Nginx doesn’t process PHP scripts. Instead. Nginx “proxies” the requests for PHP files to a backend handler. The backend handler most often chosen is PHP-FPM. This allows Nginx to excel at serving static content while also dedicating a specialized engine to PHP processing.
Apache Httpd vs Nginx
We’ll try to cover some features before we dive head first into a discussion of performance.
The Apache Httpd web server allows for the use of .htaccess files. Htaccess allow end users to configure web server parameters. Sometimes it can be a good thing. Other times it is abused.
Nginx allows for ‘included‘ configuration files which can be used to offer some configuration options to end users. The downside is that the user configuration files are included in the main configuration. If a web server restart or reload is needed, and if there are errors, then entire web server will crash.
Nginx allows for some really intense caching. With a WordPress plugin, Network Nginx Proxy Cache Purge, an entire WordPress network can be configured to cache to static html files that automatically update when changes are made. There are some considerations for any pages that include dynamic content, but for simple setups it can speed up page load times by 400% and up.
We’re not familiar with such an option in Apache Httpd. Perhaps it would not be needed, as there are WordPress plugins that claim to cache sites to html. The Nginx approach has the advantage of never loading WordPress code to show a cached page though.
PHP-FPM is the standard way to handle PHP in Nginx. Mod_php is the standard way to do it in Apache Httpd. That’s not to say that Apache Httpd doesn’t support PHP-FPM. Our anecdotal experience with such setups has been disappointing in comparison to Nginx. We like to think it might be due to the heaviness of Mod_rewrite, but we don’t have the facts to back such claims up… just faith.
Web Server Performance
by Sebastian Dabkiewicz
Sebastian’s case study shows Nginx slightly out performing Apache Httpd in serving static files.
by Albert Hidalgo Barea
Albert has written a masterful Master’s Thesis that should probably be studied in depth by anyone wishing to administrate a web server or architect a web stack for a given use case. We interpret his results as showing Nginx and PHP-FPM as top performers in most cases.
Anecdotal Experience of our own Engineers
One of our engineers provides a useful case study in which a medium-low traffic website was converted from Apache Httpd to Nginx.
The story starts out with aging software, aging servers, aging configurations and a “legacy” sticker attached to just about every component in the stack. With that said, it was quite the environment. The environment consisted of two load balancers, two static servers, two application servers, and database server. The load balancers were running Haproxy. The static servers and application servers were running Apache Httpd.
The active load balancer would proxy requests to one of the two active static servers. That static server would serve any static content it could find and then proxy any requests for dynamic content like PHP scripts to the application server running mod_php.
It was all quite interesting and looked great on paper. It was unfortunately, poorly implemented and often unstable. It was difficult to do any meaningful caching with Apache because of the complexity. Servers were constantly crashing, and any ‘high-traffic periods’ (10+hits/second) would bring the entire system to its knees. On top of all of that, the entire stack was so tightly coupled that any attempt to patch vulnerable components lead to crashing.
This entire stack was replaced by a single Virtual Machine with a single CPU at 3.2GHz and 8GB of ram (the old system being 6 cpus and 16GB+). The new stack ran Nginx and PHP-FPM. Even without aggressive server side caching (Read: only the home page), the new single server out performed the old stack by leaps and bounds in every category. Even with a loss of redundancy, the new system is more stable. At this point redundancy would be trivial to implement.
- Clone the VM
- Stick HAProxy in front of the two systems.
This anecdotal experience alone would probably be enough to convince our engineers that Nginx is the correct solution for our use case. Add on the general public consensus of Nginx’s superior performance, ease of use, and the features available…. and I think the winner is clear.
Using Nginx and an addon called ngx_cache_purge, we are rarely processing PHP scripts when we server pages. Most of our content is served from a static cache sitting in memory. <superFast />.