Simple explanation of Nginx vs Apache?
I've been reading round and round on this for weeks, whilst fighting a losing battle trying to get a working nginx server that can serve more than the root folder, and I am asking myself "Is all this hassle just to get it to work really worth it"?
Would anyone like to offer up a quick opinion on Nginx vs Apache?
What I need is: No mail (gmail handling it), some php (phpBB/phpmyadmin) a bespoke site I'm doing with Zend Framework that could have lots of connection but a very low data rate, and a few mysql databases.
I was put off Apache after looking at how it handles lots of requests, as opposed to nginx, which seems to offer much better CPU and load.
So far though, I can't even get phpmyadmin working, with it spitting out it can't find mysql, mysqli etc (even though it's php5, it shouldn;t need it, and mysqli.so is loaded as an extension sucessfully). It's just nothing but bloody trouble and I suppose I'm looking for a bit of feedback before I say "stuff it" and go back to apache
So, if anyone would like to share their thoughts here I would be very grateful to hear it
EDIT: I should add that I think the reason it's like a losing battle is that nothing is optimized to work with nginx and everything works well with apache.
19 Replies
@tentimes:
I was put off Apache after looking at how it handles lots of requests, as opposed to nginx, which seems to offer much better CPU and load.
I got myself into a similar mental state when doing my first Linode, particularly after reviewing the forums here which can often come across (particularly a year+ back) as "apache evil, other stuff good" upon first glance. As with most things, it's not quite that black and white. But at the time I got scared away from using Apache and tested lightppd and nginx (which I had to build locally to get a recent enough version) and settled on nginx.
Now I was mostly static, or proxying to my own application server, but then on one of my servers I needed to support cgi, so I ended up installing Apache anyway just to let nginx forward the occasional cgi request to it. I've also got a CMS now I'm testing that has various custom stuff provided as an Apache .htaccess so I need to use Apache or manually convert that into nginx compatible configurations.
> So, if anyone would like to share their thoughts here I would be very grateful to hear it
EDIT: I should add that I think the reason it's like a losing battle is that nothing is optimized to work with nginx and everything works well with apache.
If I were doing it all over again, and I had applications for which an Apache configuration was quickier/easier (even if just for me) or more standardized, I'd just start with Apache, and only worry about other options if performance became an issue. That may be a minority position in these forums, but over time I've done some of my own configuration testing and benchmarking, and the gap between a well-tuned Apache configuration and nginx is nowhere near as large as it is sometimes made out to be. Also, I pretty much know Apache will have every knob and bell I might need, plus I know I can always add nginx in front of it if needed later.
In terms of the core issue - Apache default configurations on many distributions are set to permit the use of lots of memory (by allowing many client processes, each of which can be fairly large especially when using the prefork mpm while embedding interpreters like php with mod_php). And using up all your memory, causing swapping, is a sure fire way to kill your Linode's performance.
Conversely, a default nginx setup tends to have a smaller working set, not to mention forcing you to immediately deal with offloading php to a separate process since it has no equivalent to mod_php. But that same offloading can be done with Apache too.
And some basic Apache tuning can very quickly even the playing field. First, make sure that your peak client count will fit in memory, since swapping will kill you. Then see if it that configuration can handle your load.
If not, a next step can be to offload php to a separate process (ala fcgi) so you can let Apache handle static requests with fewer resources, and manage your php resources independently. Or, you can consider fronting apache with nginx for static resources and only using Apache for php.
But I'm convinced that for the vast majority of purposes, Apache is just fine once tuned slightly, and it's certainly the case that various packages integrate more cleanly with Apache or at least have better documentation on doing so. They might also include .htaccess files to drop into Apache while you'll have to convert them for nginx use.
That's not to say that ngnix (or lightppd) or other alternatives are bad. I still use nginx on many of my nodes, and it's an absolutely excellent server. Yes it can have a smaller memory footprint than Apache, and while my own testing places them pretty close, under static loads I wouldn't be surprised if its raw rps limit is higher than Apache. But it's also something you can evolve to when needed.
Life's complicated enough when just getting going with a VPS - if you have an easier time getting your particular application stack working with Apache, I say start with that and then tune as needed. Just be sure to check your distribution's default configuration to be sure that you don't start off thinking you're fine only to have it die under the first heavy request load (which is what I think happens to a lot of people unexpectedly, and ends up turning them off of Apache). So once you're up, stress your node with 'ab' with enough parallel requests to be sure your working set is appropriate, and only then judge what further tuning you may need.
– David
I'm just weighing it up here and the things I'm thinking are:
This is primarily a functional server for server side to my app.
The server side processes small request for timetabling, with a couple of yes no responses and possibly some booking, done on a mobile device (java mobile app, Android etc). So data is minimal and I'm not serving up content.
I'm writing in Zend Framework for server side
I can decide on the max amount of concurrent users per server and split onto another node cost effectively
If I can handle 100 simultaneous sessions on one server then I'm laughing, as I really can't see it going that high.
So it's 100 maxclients with simple php with parameter passing.
And I wonder is Apache good for that on a Linode, and if not would Nginx with fastcgi handle it better? I'm not sure Nginx as a proxy would help much there as I'm not really serving up content.
Time to mull it over some more, but thanks again for your thoughts - I think I need to do some stress testing
You're not likely to get 100 Apache processes on a Linode 512 for example, but then again, neither are you likely to get 100 PHP processes beneath a fastcgi server either.
But from the description of your setup, I doubt you need anywhere that many processes in terms of simultaneous requests. But for example, you can set up your stack, hit a URL that executes as much of it as possible with ab and see how many requests/s you can process with Apache tuned to fit within memory. That'll give you some concrete data on what you can support.
– David
@tentimes:
That's a relief! What's "ab" mean please?
Apache Bench
A simple, but very useful, way to test your server's ability to handle connections. Start small and work your way up. Number of requests (-n) and concurrency (-c) are probably the first two to play with.
@db3l:
I've done some of my own configuration testing and benchmarking, and the gap between a well-tuned Apache configuration and nginx is nowhere near as large as it is sometimes made out to be.
Although I am usually a big fan of Nginx, I have to agree with your previous point in that it is sometimes easier to just use Apache, when you have applications, CMS'es and so on tailored out of the box for Apache (.htaccess etc), rather than having to convert configurations and - rarely - even adapt applications to work with Nginx because of the different modules and components available. This is especially true if traffic and resources are not really a problem yet.
But broadly speaking about performance, I have to say that in any tests I have ever done, I have always seen a significant advantage for Nginx with static files, sometimes a massive difference. For dynamic content instead, usually I have seen little to no difference, and actually for PHP pages Apache in some cases seemed to me slighly faster with both mod_php and fastcgi.
The main advantage though imho is the fewer resources used by Nginx. I've seen servers collapsing with little traffic and Apache (especially with mod_php!), as well as undersized servers with Nginx happily handling higher traffic with less memory etc.
@Vito Botta:
But broadly speaking about performance, I have to say that in any tests I have ever done, I have always seen a significant advantage for Nginx with static files, sometimes a massive difference. For dynamic content instead, usually I have seen little to no difference, and actually for PHP pages Apache in some cases seemed to me slighly faster with both mod_php and fastcgi.
Well, benchmarks being what they are I certainly won't claim that my results necessarily extrapolate to anyone else, so it's good to have other input. When I ran some comparisons last year on one of my linode 512's (hmm, might still have been a 360 at that point), both Apache and nginx served up 10000+ static requests/s and varied enough among the tests that I wasn't willing to declare either a clear winner. This was with a local ab, since even using two other Linode's in the same DC as sources caused the network to become the transaction rate bottleneck, so there was competition between ab and the servers on the same Linode too. So if there's an inflection between the two at a higher point than I could generate I wouldn't have seen it.
I do think Apache used a little more memory, but in a static configuration I think its footprint was like 6-7MB per process, and it didn't really need that many parallel processes in my tests to keep up with that request rate. I forget the nginx process size, but do recall it growing noticeably from its initial size under the load.
With that said, I wouldn't really argue a general point of nginx likely needing less memory and having a somewhat higher rps rate than Apache on average. I have a harder time with comments like "massive difference" just because I haven't seen that myself except with mis-configurations of Apache, but am willing to respect that others may have different data.
I suspect it's also likely that any such differences are present at such a point that most anyone's Linode is going to have other bottlenecks first and/or never hit a request load higher enough, even for static files, but especially for dynamic configurations.
– David
Having said that, the easiest way to get the best of both worlds is to put nginx in front of Apache as a reverse proxy, as others have suggested. Let nginx handle static files, and pass the rest to Apache.
Out of the box, Apache is configured very poorly. I've no idea why distros insist on shipping it like that. The default settings for Apache/PHP in most distros is completely inappropriate for the vast majority of installations.
@Guspaz:
Out of the box, Apache is configured very poorly. I've no idea why distros insist on shipping it like that. The default settings for Apache/PHP in most distros is completely inappropriate for the vast majority of installations.
The problem with the defaults and a linode is that those defaults are assuming lots of memory. I wouldn't say that the vast majority of installations are memory constrained like a linode is. The default is just fine if you're running on a server that has at least a couple GB of memory.
That's beside the point, though. Apache's defaults aren't good for a machine with a few gigs of RAM. They're good for a machine with a few tens of gigs of RAM. The default MaxClients is 256. With PHP, 30MB per process is not exceptionally high, so the amount of RAM that would be typically used under full load is 7.5GB. However, PHP has a default max memory per process of 128MB, so you're probably looking at a theoretical max RAM per process closer to 140MB, in which case you'll need 35GB of RAM.
You see the problem here? Out of the box, Apache/PHP can consume up to 35GB of RAM when under full load. How is that even remotely sane for a typical installation?
EDIT: That's not to say that the defaults won't work most of the time with a few gigs of RAM. The problem is when you get a traffic spike. Properly configured, with mpm_worker and fastcgi, a huge load spike will not consume more RAM than is available, leading to a slow but accessible website. Out of the box, with any significant load spike, Apache will OOM the machine and explode spectacularly to the extent where you'll need to reboot the box because the thrashing will be so bad you won't even be able to SSH in.
@Guspaz:
Properly configured, with mpm_worker and fastcgi, a huge load spike will not consume more RAM than is available, leading to a slow but accessible website.
Just out of curiosity, what are the default settings like for mpmworker and fastcgi? Are they more reasonable than the default settings for mpmprefork and mod_php? Are they just as prone to OOM if used on a Linode 512? Or does the setup require so much manual tweaking that it's pointless to talk about the defaults anyway?
This week I've bought a new linode to test a new server and put cherokee (similar to nginx or lighttpd) as web server and done some tests with loadimpact.com and ab.
I've tuned a lot my apache config (to not eat my ram, was using 20 maxclients) and was getting miserable results when more than 20 clients at that test, even the 10 clients test was bad compared with cherokee, got 3-4sec page load for 10 clientes and climbimg to 10sec with 30 clients, more than 20sec with 50 clients, using php-fcgi/apc. (this with Joomla and a working site)
Now, with cherokee, the same site, and php-fpm, It does in 1.2sec the 10 client, the 50 client does in 1.4sec!!!!! Absolutely no changes in configurations (only php-fpm), and memory consumed is abysmal low, ~150mb with mysql/cherokee/php-fpm/apc on the 50 client test and ~100mb idle.
The apache server with same apps uses 350mb when 50client test and ~150mb idle!
Just my 2cents, but I'll won't come back soon to apache2 anymore…
@hybinet:
@Guspaz:Properly configured, with mpm_worker and fastcgi, a huge load spike will not consume more RAM than is available, leading to a slow but accessible website.
Just out of curiosity, what are the default settings like for mpmworker and fastcgi? Are they more reasonable than the default settings for mpmprefork and mod_php? Are they just as prone to OOM if used on a Linode 512? Or does the setup require so much manual tweaking that it's pointless to talk about the defaults anyway?
It's not pointless to talk about defaults, because most people don't change them. Out of the box, Apache will explode under load on anything but an enterprise-grade server (and a high-end one at that). Out of the box, the default settings for lighttpd/php will work perfectly fine with 512MB of RAM under heavy load.
My point is that the same thing can be achieved with Apache, but not without manual tweaking. Apache's defaults are not sane.
To answer your other question, mpm_worker defaults to 16 processes with up to 25 threads each. Decoupled from PHP, the memory requirement here is pretty low.
As for the default php fcgi settings, I couldn't tell you for Apache, as I've not set that up. For lighttpd, it's 2 parent processes with 4 children each. I'll admit that the theoretical memory usage there is probably about 1200MB, but that's an order of magnitude lower than Apache. PHP memory load is determined by what you run, not how much of it you run, so typical memory usage for PHP is going to fit inside that 512MB.
Tweaking either Apache or lighttpd can reduce memory usage farther, obviously.
I saw this and I know is 10 years old. If you have any update opinion for Apache esp. WordPress hosting please comment to mine.
https://www.linode.com/community/questions/22077/litespeed-vs-apache-for-wordpress
Because now, Litespeed is marketing a lot. And I know Apache and Nginx is free but they said it is dead for HTTP3 speed.
HTTP3 is HTTP2 over UDP. If you're going to run a large WP site with a lot of traffic, I wouldn't trust it.
User Datagram Protocol (UDP) is one of the two transport layer protocols…the other being Transmission Control Protocol (TCP)…in the IP suite. Unlike TCP, UDP is unreliable and connectionless. So, there is no need to establish a connection prior to data transfer. It really is unreliable…
Google and FaceBook use it but they have massive hardware infrastructure to mitigate UDPs unreliable/connectionless nature. You don't have that. Also, HTTP3 has very limited platform support among mainstream Linux distros because it's such a new RFC (in fact, QUIC is an RFC…HTTP3 is not). It's coming but not there yet (IMHO).
IMHO, what Litespeed is saying is marketing hype…efforts by a much smaller competitor to create FUD about two larger ones. Standard marketing practice. nginx has published an HTTP3 roadmap:
https://www.nginx.com/blog/our-roadmap-quic-http-3-support-nginx/
apache2 seems to be waffling…it's a much bigger job for them…esp for TLS.
IMHO, most of the people who complain about apache2 performance don't have it configured correctly. I can't comment about nginx as I don't use it.
-- sw