Apache or Nginx. This is a question that many website administrators have considered. It’s a question that I’ve also considered several times, and again just the past week. Apache is the most popular web server on the Internet. Nginx, on the other hand, is designed for crazy fast performance. Fast is always good to have.
I’ve been making some incremental changes to my website. It’s all under the hood. One thing that inevitably surfaces is about performance. I’ve been using Apache from the beginning. It’s completely functional, and does everything I need it to do. It might not be the fastest web server software, but it’s no slow coach either.
Nginx is the newer kid on the block. It was first released in 2004, so it’s not really all that new anymore. It does have a reputation for performance, both in terms of raw speed and ability to scale to significant load.
But is Nginx really faster? I know it’s popularly believed to be faster than Apache, but I’m the sort who must try, see, and believe. Well, at least if it’s something practical that I can do.
My test would be on my live WordPress blog website. It is a typical LAMP setup: Linux, Apache, MariaDB and PHP (via mod_php). On the exact same system, I installed and configured Nginx. Since there’s no equivalent of mod_php in Nginx, I took the opportunity to move from mod_php to php-fpm. So at this point, everything’s absolutely identical, and I can just switch between Apache and Nginx anytime with ease.
You know what? I found negligible difference between Apache and Nginx. My test was merely intended to replicated the realistic type of volume my website handles. It isn’t a lot. I was more concerned about the speed at which the web server could respond to requests. I had expected to see some clear wins with Nginx. But no.
Perhaps Apache has caught up with Nginx. I didn’t see much difference in memory utilisation either. Yes, that’s another surprise for me.
If you must know, Apache actually came out slightly better, but it’s only less than 3% faster than serving requests and just about 3% better at memory.
Just to shed a bit more information, my Apache is version 2.4.6, not the latest at all, but I do use their new mpm_event worker. This is the latest of Apache’s multiprocessing model.
I made up my own test suite, in case you were wondering. Many people like to use Apache’s ab, but ab cannot handle testing of mixed URLs, which would be more realistic since a website will contain a mixture of resource types. Nevertheless, I did run Apache ab as well to get a sense of its numbers. There are some numbers, hitting the WordPress main index page.
Apache | Nginx | |||
---|---|---|---|---|
c=4 | c=8 | c=4 | c=8 | |
Requests per sec | 2.56 | 2.64 | 2.61 | 2.63 |
Mean time per request (ms) | 1564 | 3003 | 1530 | 3040 |
Transfer rate (kB/s) | 105.3 | 108.6 | 107.46 | 108.19 |
50% of requests served in (ms) | 1504 | 3004 | 1504 | 3018 |
90% of requests served in (ms) | 1774 | 3174 | 1576 | 3187 |
100% of requests served in (ms) | 2068 | 3934 | 2139 | 3610 |
The test were done with concurrency of 4 and 8. I didn’t go for too many, because realistically my website wouldn’t get all that busy.
You see again from the above table that the difference between Apache and Nginx seems rather negligible.
The Nginx tested is version 1.9.12. It’s the latest. Both Apache and Nginx have Google’s Pagespeed module installed. I used the binary package provided for Apache. On Nginx, there’s no package available, so I built Nginx with Pagespeed myself, with this patch to fix some bug with multiple Vary headers being erroneously emitted.
I do find some benefits with Nginx. FIrst, it has HTTP2 support. Apache has it from 2.4.17, but it’s not in any CentOS package repo. HTTP2 has real benefits. I benchmarked on a real Chrome browser. Nginx with HTTP2 was sending pages faster to Chrome than Apache could. HTML page was fully received in 1.5 s on average with Nginx, versus 2 s with Apache. The webpage with all resources gets delivered in 2.6 s with Nginx, verus 3.2 with Apache. Good, Nginx is fast. However, on closer scrutiny, it turns out all the speed advantage basically comes from quicker connection setup. That’s basically a benefit of HTTP2, not of Nginx per se.
It seems to be that whether Apache or Nginx, the web servers themselves aren’t very different. The problem is in other features that I want.
- I want Google Pagespeed. It’s really useful in improving content delivery performance, particularly when you’re working with other software and can’t control HTML output by hand.
- HTTP2 seems to offer real benefits. Any modern website ought to adopt it now.
So now I’m in a sort of dilemma. I try as hard as possible not to compile stuffs by hand. I can do it if I need, but I prefer not to. It’s tiring to keep stuffs up-to-date. If I want Pagespeed, Apache offers me the advantage of not having to compile stuff by hand. But Apache won’t do HTTP2, not unless I get version 2.4.17 or later, which probably means I have to compile by myself anyway, and that’s precisely what I want to avoid.
There is a Nginx package repo available, up-to-date with version 1.9.12 at this time. HTTP2 is in there. The problem here is that Pagespeed for Nginx needs to be built from source.
CentOS is not going to move ahead with the Apache version. That’s how it is with enterprise Linux distros. I dislike Ubuntu, but I’m spying that their next 16.04 LTS release appears to include Apache 2.4.17. The current Ubuntu 15.10 does not. So I’ve got no solution with Ubuntu either. 16.04 won’t be that long a wait though.
Decisions, decisions.
At time of this writing, I have Nginx running. Built from source, so that I can get Pagespeed.
I think the surprising take-away for me is that Nginx is practically not faster than Apache, HTTP2 aside.
How about trying HHVM? http://hhvm.com
My guess is that it’s the PHP that’s taking up most of the CPU and memory since it’s WordPress, HHVM should give better performance (disclaimer: I haven’t tried it myself. 🙂 )
My first try. I’m guessing from what people were saying. Nginx will show its edge over Apache only at a high enough concurrency that theading causes it to run out of memory. Not sure what event worker does. I’d be interest if you threw loader.io until something breaks.
You should go with HHVm or PHP 7 (if you are not already on it) next.
For me, it makes a diff https://lesterchan.net/blog/2015/03/20/lesterchan-net-on-nginxphp-fpm-mariadb/ and https://lesterchan.net/blog/2015/04/28/lesterchan-net-on-hhvm/
Heh yes, I considered HHVM. But it’s yet more things to compile… Trying to minimise the maintenance burden. I dislike Ubuntu, but I might just consider an early upgrade to 16.04 because I noticed it includes a version of Apache that supports HTTP2.
Oh yes. I did test APC and found a measurable improvement than without. I supposed it’s obvious.
To add on, nginx is much more efficient with RAM usage than Apache.
Trouble is, I didn’t find it measurably so in my tests.