Why is it not recommended to serve static files from Node.js?

I read somewhere that static files should be served from Nginx which sits in front of Node.js. Why is it not recommended to serve from Node.js directly? Is express.static() not good for production usage?

Tags:#nodejs
Denny Trebbin's photo

express.static or koa.send consume cpu time which isn't available for your main app loop until file(s) are sent. In details - express.send cares too much for dynamic stuff like settings response headers, calculating response status, calculating size of files, finding correct mime types, etc, etc, etc. this computing happens on your main app loop but this main loop should be used as much as possible exclusively for your business computations only.

nginx is much better used for serving statics. because it does some clever tricks that can't be done by node.js, like linking mime types semi statically based on file extensions only. It has pre-baked response headers and response status and it has a template for such such responses. nginx not only spends less time for building response headers and status, but also uses os features when available to speed up even further. Additionally nginx runs on different cpu core(s)/thread(s) other than your node.js app.

node.js hint: you always wanna do as less as possible on your main app loop.

I hope this makes any sense.

Show +2 replies
Denny Trebbin's photo

you'r welcome jerry :)

Margaret's photo

Perfect. Completely makes sense. Thanks for the detailed answer Denny!

Jan Vladimir Mostert's photo

NodeJS (just like Tomcat, Apache, etc) will probably do fine serving static files, while NGINX will give you much better performance since it was built in C and supports the sendfile system call which is as fast as you can get on a Linux OS.

See: blog.modulus.io/supercharge-your-nodejs-app..

The test I ran was 10,000 requests using 40 concurrent connections. Node.js averaged 862 requests/sec and Nginx averaged 1,608 requests/sec. This means Nginx can handle roughly double the throughput in my test environment.
Alexander Craggs's photo

Incorrect!

Node.JS is built in C, just like NGINX is. The difference is NGINX is static and can do pre-optimizations which wouldn't make sense for Node.JS to do. That being said, do use NGINX if you are expecting a large amount of traffic, it is much faster.

Sandeep Panda's photo

I agree with Jan. Nginx can be really fast while serving static files because of the sendfile system call. Also your Node.js app should be used to generate dynamic content. Requests for non-dynamic resources like static files should not come to Node and clog the process. These resources should be served by Nginx.

Connor Leech's photo

interesting. For all my MEAN stack apps I use: router.get('/*', function(req, res) { res.sendFile(rootPath + 'public/index.html', { user: req.user }); }); to serve up the angular.js portion (static files). source: github.com/cleechtech/mean-starter/blob/mas..

Allan Ebdrup's photo

If you have a public facing app, another option that I think is preferable to sending static files from nginx, is setting up a CDN proxy (like Amazon cloudfront). It's much easier to set up, performs (much) better across the world, and you can keep deploying your app/website as though it's one app. Just cache everything forever, and give files a new URL when you change them.