A reverse proxy is a server that sits in front of a website and handles incoming requests on the site’s behalf. Visitors talk to the reverse proxy; the reverse proxy talks to the real application server behind it. To the visitor it looks like they are talking to your site directly.
If a forward proxy stands in for the visitor, a reverse proxy stands in for the site.
Why you would want one
Reverse proxies do five useful things at once, which is why almost every serious website has one:
- Terminate TLS. The reverse proxy handles HTTPS with the visitor and forwards plain HTTP to your app internally. You update one certificate, not one per service.
- Load balance. Requests fan out across a pool of application servers. If one dies, the reverse proxy stops routing to it until it comes back.
- Cache. Static assets — images, CSS, JavaScript — get served straight from the reverse proxy, sparing the application from doing the same work again.
- Compress and rewrite. Gzip or Brotli compression, header rewrites, redirect rules — all live in the reverse proxy so your app doesn’t have to.
- Filter and protect. A reverse proxy is where you enforce rate limits, block bad IPs, and add DDoS protection.
Reverse proxy vs load balancer
A load balancer is a reverse proxy whose main job is picking which backend server takes each request. Every load balancer is a reverse proxy; not every reverse proxy is primarily a load balancer. In practice modern tools do both, and the distinction is mostly historical.
Reverse proxy vs forward proxy
| Forward proxy (e.g. AnyProxy) | Reverse proxy (e.g. Cloudflare) | |
|---|---|---|
| Stands in for | The client | The server |
| Sits between | You and the internet | The internet and a website |
| You use it to | Open blocked sites | You don’t — the site uses one |
| Common examples | AnyProxy, Squid, corporate web filters | Nginx, Cloudflare, HAProxy |
When to add one to your site
You almost certainly already have a reverse proxy the moment you put a site on the internet, even if you didn’t call it that.
- Deploy on Vercel, Netlify, Cloudflare Pages — you’re using their reverse proxy.
- Deploy on AWS with an Application Load Balancer — the ALB is a reverse proxy.
- Run Docker Compose with an Nginx container in front — that Nginx is a reverse proxy.
The moment your site has more than one instance, needs TLS, or serves static assets, adding an explicit reverse proxy (Nginx, Caddy, or a managed CDN) is the standard move.
The one gotcha
Every reverse proxy hides the visitor’s IP from your application unless you configure it not to. You need to trust the X-Forwarded-For or Forwarded header that the proxy sets, and configure your app to read the visitor’s real address from there. Otherwise every request looks like it came from the proxy — which will confuse rate limiting, logging, and geolocation.
Set this up once at deploy time. Every framework has a middleware for it (Rails’ ActionDispatch::RemoteIp, Django’s USE_X_FORWARDED_HOST, Express’s trust proxy, and so on).
Related reading
- What is a proxy server? — the forward-proxy sibling article.
- Proxy vs VPN — for when the tab-vs-device distinction matters.