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?
Node.js developer. Experimenting with bleeding-edge tech. Irregularly DJ. Hobby drone pilot. Amateur photographer.
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.
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.
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.
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.
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.