99

Is there any benchmark or comparison which is faster: place nginx in front of node and let it serve static files directly or use just node and serve static files using it?

nginx solution seems to be more manageable for me, any thoughts?

artvolk
  • 9,448
  • 11
  • 56
  • 85
  • 3
    I would say it also depends on the amount of configuration and code you have to write to use one server over the other. If you don't expect to go IPO and your app server is already configured and doing everything you need, then you could just stick with it until it's not enough. – m33lky Apr 02 '12 at 21:44

8 Answers8

129

I'll have to disagree with the answers here. While Node will do fine, nginx will most definitely be faster when configured correctly. nginx is implemented efficiently in C following a similar pattern (returning to a connection only when needed) with a tiny memory footprint. Moreover, it supports the sendfile syscall to serve those files which is as fast as you can possibly get at serving files, since it's the OS kernel itself that's doing the job.

By now nginx has become the de facto standard as the frontend server. You can use it for its performance in serving static files, gzip, SSL, and even load-balancing later on.

P.S.: This assumes that files are really "static" as in at rest on disk at the time of the request.

m33lky
  • 7,055
  • 9
  • 41
  • 48
  • 7
    Just a minor note: node.js also supports `sendfile` - but it seems you have to write some code, see eg. http://blog.std.in/2010/09/09/using-sendfile-with-nodejs/ – tuomassalo Apr 09 '12 at 19:14
  • Outside of serving static content, why does Nginx performance better than just exposing the main web server (Tomcat/Jetty/IIS, etc) on the public-facing domain? – raffian May 01 '12 at 18:16
  • 1
    If a request is made to your app, that request won't be made magically faster by routing it through nginx first (it can be noticeably faster in the best case when nginx handles static CSS and js, gzip and SSL). However, nginx is also one of the best software load balancers, so this might be critical as most servers are notorious for flipping out at moderately high loads. – m33lky May 01 '12 at 18:39
  • But you can server the files in an asynchonous way using Node.js. Can you do that with NGINX? – Dragos C. Jun 04 '13 at 11:38
  • 1
    @lwansbrough bring those benchmarks to the table. At least one person in this topic has done experimentation of his own. – m33lky Jul 12 '15 at 03:18
84

I did a quick ab -n 10000 -c 100 for serving a static 1406 byte favicon.ico, comparing nginx, Express.js (static middleware) and clustered Express.js. Hope this helps:

enter image description here

Unfortunately I can't test 1000 or even 10000 concurrent requests as nginx, on my machine, will start throwing errors.

EDIT: as suggested by artvolk, here are the results of cluster + static middleware (slower):

enter image description here

gremo
  • 47,186
  • 75
  • 257
  • 421
  • Thank you, very helpfull! Did you use this middleware for favicon: http://www.senchalabs.org/connect/favicon.html or just served it as static file? – artvolk May 20 '13 at 07:01
  • @artvolk the favicon one :) – gremo May 20 '13 at 08:59
  • It seems that favicon middleware caches the file in memory. Static middleware should be even slower than in your tests. – artvolk May 20 '13 at 10:47
  • @artvolk good to know, thanks! By the way I'm writing my thesis and the only thing that matters is to prove that nginx is faster than node, with static content. – gremo May 20 '13 at 12:04
  • 3
    Did you set NODE_ENV=production for the tests? Because that would make an incredible difference due to the caching `static` middleware will do in production. – ruffrey Jul 29 '15 at 05:32
  • 24
    for those of you who don't speak italian the x axis is # of requests, and the Y axis is number of ms that it took to serve the file. I had to google translate that because I wanted to make sure I wasn't reading the data wrong. this data was unbelievable helpful though and I really appreciate the benchmark test here. will be sticking with nginx after all – JL Griffin Feb 19 '16 at 00:03
  • also why was this not selected as the top answer? – JL Griffin Feb 19 '16 at 00:08
  • 1
    Was NODE_ENV=production set? – basickarl Aug 03 '16 at 21:59
  • Try to pass option -k to ab `ab -n 10000 -c 100` to beat the limit of 16k. http://justthesam.com/2012/05/apache-bench-ab-stalls-after-16000-requests-ephemeral-ports/ – Vlad Tsepelev Dec 02 '16 at 17:35
  • I'd be interested in tests with Node 8 turbo+ignition with `--production` - it seems node is quickly integrating V8 and their own optimizations. – Sean Newell Jun 23 '17 at 14:00
  • A bad idea to use a framework for file serving, as there is a very considerable performance penalty. Convenience and speed of development kill processing speed. Would have been more interesting to see a comparison of pure node HTTP without express. – Nikolay Schamberg Sep 15 '20 at 20:59
12

Either way, I'd setup Nginx to cache the static files...you'll see a HUGE difference there. Then, whether you serve them from node or not, you're basically getting the same performance and the same load-relief on your node app.

I personally don't like the idea of my Nginx frontend serving static assets in most cases, in that

1) The project has to now be on the same machine - or has to be split into assets (on nginx machine) & web app (on multiple machines for scaling)

2) Nginx config now has to maintain path locations for static assets / reload when they change.

Will Stern
  • 17,181
  • 5
  • 36
  • 22
11

I have a different interpretation of @gremo's charts. It looks to me like both node and nginx scale at the same number of requests (between 9-10k). Sure the latency in the response for nginx is lower by a constant 20ms, but I don't think users will necessarily perceive that difference (if your app is built well). Given a fixed number of machines, it would take quite a significant amount of load before I would convert a node machine to nginx considering that node is where most of the load will occur in the first place. The one counterpoint to this is if you are already dedicating a machine to nginx for load balancing. If that is the case then you might as well have it serve your static content as well.

ssotangkur
  • 123
  • 1
  • 6
  • 1
    "Sure the latency in the response for nginx is lower by a constant 20ms, but I don't think users will necessarily perceive that difference"? I seriously hope you guys don't do this. There is evidence that users will perceive a 1ms difference! – Navin Nov 05 '17 at 08:04
  • 7
    Citation needed – David Burrows Nov 05 '18 at 10:04
2

FWIW, I did a test on a rather large file download (~60 MB) on an AWS EC2 t2.medium instance, to compare the two approaches.

Download time was roughly the same (~15s), memory usage was negligible in both cases (<= 0.2%), but I got a huge difference in CPU load during the download:

  • Using Node + express.static(): 3.0 ~ 5.0% (single node process)
  • Using nginx: 0.3 ~ 0.7% (nginx process)
Maxime Pacary
  • 22,336
  • 11
  • 85
  • 113
0

Use Nginx to cache static files served by Node.js. The Nginx server is deployed in front of the Node.js server(s) to perform:

SSL Termination: Terminate HTTPS traffic from clients, relieving your upstream web and application servers of the computational load of SSL/TLS encryption.

Configuring Basic Load Balancing with NGINX: set up NGINX Open Source or NGINX Plus as a load balancer in front of two Node.js servers.

Content Caching: Caching responses from your Node.js app servers can both improve response time to clients and reduce load on the servers, because eligible responses are served immediately from the cache instead of being generated again on the server.

Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
0

That's a tricky question to answer. If you wrote a really lightweight node server to just serve static files, it would most likely perform better than nginx, but it's not that simple. (Here's a "benchmark" comparing a nodejs file server and lighttpd - which is similar in performance to ngingx when serving static files).

Performance in regard to serving static files often comes down to more than just the web-server doing the work. If you want the highest performance possible, you'll be using a CDN to serve your files to reduce latency for end-users, and benefit from edge-caching.

If you're not worried about that, node can serve static files just fine in most situation. Node lends itself to asynchronous code, which it also relies on since it's single-threaded and any blocking i/o can block the whole process, and degrade your applications performance. More than likely you're writing your code in a non-blocking fashion, but if you are doing anything synchronously, you may cause blocking, which would degrade how fast other clients can get their static files served. The easy solution is to not write blocking code, but sometimes that's not a possibility, or you can't always enforce it.

Brad Harris
  • 1,520
  • 9
  • 12
  • 9
    This is all nonsense. This question is about *nginx* not Apache. Both nginx and node use libev for their event loop. Nginx is going to be many times faster than node. One of them doesn't have the overhead of a VM, and is written specifically to do this operation on your file system. – Evan Carroll Sep 05 '13 at 03:23
  • 1
    libev was early node. Libuv has adopted this role to allow node to run crossplatform. – tsturzl Jan 31 '14 at 00:21
  • 1
    I don't see how asynchronous code factors into this. Node's performance will be far worse than that of Nginx and it'll likely be because of blocking I/O which you'd run into when you've got a bunch of clients asking you to read files from disk. Best practice is to always use Nginx for static assets so your Node app can handle application logic. We could talk about theoretical scenarios where Node will perform better but in the real world Nginx will win by a mile 9 times out of 10. – wgp Jul 13 '15 at 19:07
-13

I am certain that purely node.js can outperform nginx in a lot of aspect.

All said I have to stay NginX has an in-built cache, whereas node.js doesn't come with it factory installed (YOU HAVE TO BUILD YOUR OWN FILE CACHE). The custom file cache does outperform nginx and any other server in the market as it is super simple.

Also Nginx runs on multiple cores. To use the full potential of Node you have to cluster node servers. If you are interested to know how then please pm.

You need to deep digger to achieve performance nirvana with node, that is the only problem. Once done hell yeah... it beats Nginx.

user2379441
  • 148
  • 6
  • 1
    you need to bring some facts, as I would like to believe what you are saying but, need benchmarks, if based on the real world, great! but not edge cases – Stefan Rogin Mar 08 '15 at 13:34
  • 7
    The funny thing is this answer has as many facts as the chosen answer with the most up-votes. I think people just prefer a web server in front because that's how they were taught to do it in [insert any other web application technology]. This is not a good answer but +1 out of pity. –  Mar 24 '15 at 16:34