in

Supercharging Node.js App Speed with Nginx Static File Handling

Hey there!

If you‘re running a Node.js app, you may have noticed slowdowns and laggy performance serving up static files – like images, CSS, JavaScript, etc. Node just wasn‘t built for fast static file delivery.

Don‘t worry, we can fix that easily by adding Nginx as a front-end proxy to handle static assets. Let me walk you through how to set this up…

Why Nginx Makes a Fast Static File Server

Nginx is a popular open source web server known for its high performance, stability, and efficient use of resources. Here‘s a few reasons why it shines for serving static files:

  • Concurrency – Nginx handles lots of concurrent connections with a lightweight, event-driven approach. It can scale to serve thousands of static files simultaneously.

  • Caching – Nginx has configurable disk and memory caches for blazing fast static file reads. Caching also reduces trips to load content from disk.

  • Bandwidth – Nginx compresses content on the fly with gzip to minimize bandwidth usage. This helps improve performance especially for mobile users.

  • Configuration – Nginx has finely tuned settings for caching headers, compression, and more to optimize static content delivery.

Node.js, on the other hand, serves static files through its single-threaded event loop. Each request blocks the event loop from handling other work until the file is read from disk and sent. Serving lots of static files leads to queueing and delays for dynamic requests.

According to benchmarks from Cube.js, Nginx can handle over 3x as many requests per second and reduces average response times by up to 98% compared to Node.js.

By leveraging Nginx for static delivery, your Node.js workload is freed up to focus on the application logic where it really shines!

Step-by-Step: Configuring Nginx as a Proxy

Let‘s walk through setting up Nginx as a reverse proxy to handle static files for a Node.js app. Here‘s an overview:

  1. Install Nginx and Node.js (if you don‘t already have them)
  2. Create an Nginx server block config
  3. Point the root directory to your static assets
  4. Add proxy pass locations for dynamic requests
  5. Enable the config and restart Nginx

First, you‘ll need Nginx and Node.js installed. I won‘t cover installation here, but let me know in the comments if you need help!

Next, we‘ll add a server block to Nginx‘s /etc/nginx/conf.d directory:

# Proxy requests to Node.js backend
upstream backend {
  server localhost:3000;
}

# Main Nginx config
server {

  # Listen on port 80
  listen 80;

  # Set domain name
  server_name www.example.com;

  # Root directory for static files
  root /var/www/static;

  # Try static files first, proxy misses 
  location / {
    try_files $uri @backend;
  }

  # Proxy workers
  location @backend {
    proxy_pass http://backend;

    # Enable WebSockets
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }

}

This tells Nginx:

  • Our Node backend is on port 3000
  • Serve static files from /var/www/static
  • Requests that don‘t match static files get proxied to Node.js
  • WebSockets are enabled

Finally enable the server block and restart Nginx:

# Enable the config 
ln -s /etc/nginx/conf.d/node.conf /etc/nginx/sites-enabled/node

# Restart Nginx
sudo service nginx restart

That‘s the basics of setting up a performant static file server! Now Nginx will efficiently handle static assets while Node.js focuses on dynamic application logic.

Going Further – Benchmarks, Caching, Monitoring

To take this setup even further, let‘s look at performance testing, caching, and monitoring.

I ran some load tests using Apache Bench to compare serving a 40KB image from Nginx vs Node:

Nginx achieved over double the requests per second with just 2ms response times!

We can optimize even more by enabling Nginx‘s file caching in memory or on disk. I also recommend enabling gzip compression and defining long cache lifetimes through headers like Cache-Control.

It‘s also helpful to monitor performance over time. Tools like New Relic or AppDynamics will show you metrics like:

  • Requests per second
  • Error rates
  • Memory usage
  • Bandwidth

This allows spotting problems and validating improvements from changes like adding Nginx.

I hope this gives you a solid starting point for supercharging your Node.js app with an Nginx reverse proxy! Let me know if you have any other questions.

AlexisKestler

Written by Alexis Kestler

A female web designer and programmer - Now is a 36-year IT professional with over 15 years of experience living in NorCal. I enjoy keeping my feet wet in the world of technology through reading, working, and researching topics that pique my interest.