Serving small static files: which server to use?
nbonvin.wordpress.com
nbonvin.wordpress.com
so what if nginx can serve a theoretically higher number of static files/second more than something else. are you actually serving that much traffic with no headroom in terms of extra servers and load balancers? do microseconds of computational time per request really matter when your outbound packets can get delayed by milliseconds in the network or dropped completely?
there are plenty of reasons to like one server over another, but is .0000000001 seconds/request overhead really one of them? http servers can have wildly different behaviors regarding HTTP streaming, working models, extensions, etc. how about the fact that varnish is a caching proxy that doesn't really replace something like nginx, lighttpd, apache?
he's also backing varnish with a ramdisk that takes 25% of his memory (for a 100b file, no less!) when comparing it to the others. probably not the best designed test out there.
> Again, keep in mind that this benchmark compares only the servers locally (no networking is involved), and therefore the results might be misleading.
i don't know why anyone would publish "misleading" benchmarks
i know it's less fun and there are no numbers involved, but what about a real rundown of some of the subtle differences between the servers and some of their more unique features (besides async/threaded)? that's something i would find useful reading, but i guess it's not as easy as firing up ab.
a while back when tornado (for python) came out, there was a whole slew of benchmarks comparing it to twisted. as a guy who uses twisted a lot, i was interested. all the benchmarks said tornado was faster by maybe a hundred or a couple hundred requests/sec and therefore was the superior framework.
the big question is, what difference does it make? not a single article i read mentioned the fact that twisted has a really awesome streaming API, has great TCP and UDP level support, has support for a ton of other protocols (and writing your own), or is insanely useful for non-web projects. i never read about a single feature tornado had either or why one is worth investing time in than another.
same thing for this "benchmark". i might as well write off varnish, since it serves fewer requests/sec than nginx, right? wrong! it's a different thing all together -- no mention of that anywhere in the article though. the author just says (in not so many words) it's a piece of crap compared to nginx.
the whole point of micro-benchmarks is to show one single use case and which option comes out the fastest. now if you ever need to serve small static files really god damn fast you know which web server to use.
do you really recommend operating like that?
If someone with a less optimized configuration is wondering what in his test configuration allows him to obtain those results, here is a brief recap:
1- Tests performed with ab with keepalive enabled on both the client and server
2- open_file_cache or similar options: this enable file caching, so basically the server is no more i/o bound
3- Furthermore, enabling tcp nodelay (that disables nagle alg, usefull when we have small tcp responses) and disabling access logging (this depends on how logging is implemented, if non-blocking and on a separate thread (not a worker) disabling it doesn't improve the results) could help a bit.
Being a cpu-bound test, having the client on a separate machine would have likely increased the results but i doubt it would have changed the performance ratio among them, after all in every test we had the same client with the same overhead.
Also, "The client as well as the web server tested are hosted on the same computer", which is pretty poor design, to be honest.
By hosting the web server and the client on the same computer, he is testing one aspect in isolation of others. This is a good thing, and is generally the way in which scientific tests advance knowledge.
Luckily this benchmark is incredibly simple. It's not a complex system as the test is using a single set of data with two pieces of software in a single contained environment; the only thing that changes is one piece of software and one configuration: the server. Separate the server/client and your test is still the same, only with extra resources for the server and client to take advantage of (and less network bandwidth and higher latency). Knowing how http clients work, and knowing how http servers work, is it possible that the client or server could be utilizing resources in such a different way after being separated as to skew the results in a significant way?
I don't believe so. Even if you saturated a 1Gbps network link, you will see differences in CPU time between processing of requests and differences in memory use, and unless they are all fast enough to saturate that link you will see some servers process more requests than others. If you want to verify this you can follow the benchmark's set-up and try on two separate machines and let us know if there's a significant difference.
Yes, maintaining constants and only altering one variable. But this test has an 2nd variable, that is altered into a special state for all of the experimentation, and then we make the leap into assuming that these results are anything other than pretty to look at when the 2nd variable is in any other position.
This is a good test for seeing which server runs best with a load testing client competing for resources on the box and using the loopback network. Thats it.
The problem is you can't test without a network stack at all, you can only test with a different network stack. Whats to say the particulars of the loopback network aren't causing more issues to be introduced to the validity of the results than the full TCP/IP stack you're trying to avoid influencing the results? Nothing, that's what.
Personally, I find this to be a welcome change from the typical "oooh-look-at-the-shiny-graphs" mentality that has become so pervasive on HN with regards to performance testing.
Keep up this spirit of questioning, and you'll discover a lot of interesting secrets. (For example, a placebo is 87% as effective as the 5 major antidepressant brands. Also, the CIE 1931 "color space" is a flawed system which is only roughly accurate.)
In general, anyone who presents statistics (of anything) should be subjected to a lot of skepticism. Scientific knowledge can only advance by truly testing one variable and only one variable.
With the notable exception of nginx, of course.
"Regarding the resources used by each server, Nginx is the winner in term of memory usage, as the amount of memory does not increases with the number of concurrent clients."
So I guess the memory consumption is caused by the number of concurrent clients, and not by a memory leak.
I think more important criteria are:
1. Stability. How often are you woken up in the middle of the night because your web server is shitting the bed.
2. Configuration. Can you configure it to do all the things you will need it to do? Have others who have come before you been happy with it throughout the entire life of their product, or have they outgrown it?
3. Simplicity. Can you set it up to run efficiently without weeks of study on how this server is properly deployed? Is it easy to mess up the configuration and take your site down when making a change?
4. Generality. Are you going to need something else to sit in front of your dynamic pages, if you require them? This is also a factor in stability, if you have 2 server solutions, all else being held constant, that is twice as likely to break down or get broken during a configuration change as just one. Actually, it is much more than twice as likely, since you are spreading your competency to learn the ins and outs of 2 pieces of software, so you are less capable on each than you would have been if you just had one server solution to worry about.
So, given all this, my advice to anyone trying to make an initial decision on what webserver to use is: (Apache|nginx) (pick one only) should be your default until you believe you have a compelling reason to use something else. Both are capable of doing more or less everything you need, have lots of extensions, are widely used, and have comprehensible configuration. Once you have mastered whatever one you use, you will be able to tune it, debug performance problems, and spend the minimum possible amount of time doing server configuration and testing, and maximum time implementing features and supporting customers.
Also an interesting piece of noise missing is slow clients holding on to the connection. If you're serving up multi-megabyte files, I would guess this could become a major factor.
afaik the only way you could get over a couple thousand RPS while reading from the filesystem is due to inherent caching of the VFS and disk buffers by the operating system.
and in an asynchronous web server, connections should not be held up by slow clients. if they use a model where one thread or process handles each client connection you could definitely get starvation of resources or connections, but asynchronous models should just process stuff as it comes in and not "wait" on a slow client.