πŸ“ Tutorials

What is a Reverse Proxy? A Simple Explanation for Developers


A reverse proxy sits between the internet and your application server. When someone visits your website, they talk to the reverse proxy, which forwards the request to your actual app and sends the response back.

Your app never talks directly to the internet. The reverse proxy handles that.

Why use a reverse proxy?

Without a reverse proxy:

Internet β†’ Your Node.js app (port 3000)

Your app handles everything: SSL, compression, static files, rate limiting, and your actual business logic. That’s a lot of responsibility for one process.

With a reverse proxy (Nginx):

Internet β†’ Nginx (port 80/443) β†’ Your Node.js app (port 3000)

Nginx handles the boring stuff (SSL, compression, static files, caching). Your app just handles business logic.

What a reverse proxy does

FeatureWithout proxyWith Nginx
SSL/HTTPSYour app handles itNginx handles it
Static filesYour app serves themNginx serves them (much faster)
CompressionYour app compressesNginx compresses
Rate limitingYou build itNginx does it
Load balancingNot possibleNginx distributes traffic
Multiple appsOne app per portMultiple apps on port 80

Basic Nginx reverse proxy

server {
    listen 80;
    server_name myapp.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Now myapp.com (port 80) forwards to your Node.js app on port 3000. Users never see port 3000.

Multiple apps on one server

# app1.com β†’ port 3000
server {
    listen 80;
    server_name app1.com;
    location / {
        proxy_pass http://localhost:3000;
    }
}

# app2.com β†’ port 4000
server {
    listen 80;
    server_name app2.com;
    location / {
        proxy_pass http://localhost:4000;
    }
}

# api.app1.com β†’ port 5000
server {
    listen 80;
    server_name api.app1.com;
    location / {
        proxy_pass http://localhost:5000;
    }
}

Three different apps, all on port 80, distinguished by domain name.

Load balancing

upstream backend {
    server localhost:3001;
    server localhost:3002;
    server localhost:3003;
}

server {
    listen 80;
    server_name myapp.com;
    location / {
        proxy_pass http://backend;
    }
}

Nginx distributes requests across three instances of your app. If one crashes, traffic goes to the other two.

When you need a reverse proxy

Yes:

  • Running a Node.js/Python/Go app in production
  • Need SSL/HTTPS
  • Serving static files alongside an API
  • Running multiple apps on one server
  • Need rate limiting or caching

No:

  • Using a PaaS (Vercel, Heroku, Railway) β€” they handle this for you
  • Local development
  • Serverless functions (Lambda, Cloud Functions)

Common reverse proxies

ToolBest for
NginxMost popular, great for static files + proxy
CaddyAutomatic HTTPS, simpler config than Nginx
TraefikDocker/Kubernetes, auto-discovers services
HAProxyHigh-performance load balancing
ApacheLegacy, still widely used

For the full Nginx config reference, see the Nginx cheat sheet.