Ask five engineers "what is a reverse proxy" and you get five slightly different answers, each describing their favorite job it does rather than the thing itself. Here is the honest definition: a reverse proxy is a server that sits in front of one or more backend servers, accepts requests from clients, and forwards them on. The client thinks it is talking to one machine. Behind the curtain there could be one server or fifty.
What changed in 2026
The concept has not changed in twenty years, but the defaults have.
- Automatic HTTPS is table stakes. Tools like Caddy and Traefik provision and renew TLS certificates for you via ACME. Manually copying certificate files around is now a code smell, not a rite of passage.
- HTTP/3 and QUIC are mainstream. Most modern proxies speak HTTP/3 out of the box, so you get it at the edge without touching your app.
- The proxy and the API gateway blurred. Rate limiting, auth checks, and request rewriting that once lived in a separate gateway are increasingly config lines in the same reverse proxy.
- Managed edges got cheap. Cloudflare, Fastly, and cloud load balancers mean many teams configure someone else's proxy instead of running their own.
What a reverse proxy actually does
A reverse proxy does a handful of concrete jobs:
- TLS termination. It decrypts HTTPS at the edge so your backend can speak plain HTTP internally. One place to manage certificates.
- Routing. Send
api.example.com to one service and example.com to another, or route /images to a separate pool. This is virtual hosting and path-based routing.
- Load balancing. Spread requests across multiple backends and stop sending traffic to unhealthy ones.
- Caching and compression. Serve cached responses and gzip or Brotli payloads without changing app code.
- A single choke point for security. Add rate limits, block bad IPs, and hide backend versions and internal addresses.
A minimal Nginx reverse proxy is this small:
server {
listen 443 ssl;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
That X-Forwarded-For line matters: once traffic passes a proxy, your app sees the proxy's IP unless the proxy forwards the client address.
Reverse proxy vs forward proxy vs load balancer
These three get mixed up constantly; direction and beneficiary separate them.
A forward proxy sits in front of clients and represents them to the outside world — think a corporate filter on employee web traffic. A reverse proxy sits in front of servers and represents them to clients. A load balancer is just one feature: spreading traffic across backends. Every load balancer does reverse-proxy work; not every reverse proxy only balances load.
| Tool |
Sits in front of |
Main job |
Who it hides |
| Forward proxy |
Clients |
Outbound filtering, anonymity |
The client |
| Reverse proxy |
Servers |
Routing, TLS, caching, LB |
The servers |
| Load balancer |
Servers |
Spread traffic, health checks |
The server pool |
| API gateway |
Services |
Auth, rate limit, versioning |
The service mesh |
Picking a tool without overthinking it
For most teams the choice is boring in a good way. Caddy if you want automatic HTTPS and a config file a human can read. Nginx if you want the battle-tested default with endless documentation. Traefik if you are on Kubernetes or Docker and want the proxy to discover services automatically. HAProxy if load balancing at scale is the whole point. And on a cloud, its managed load balancer or Cloudflare may be all you need.
Do not agonize; the config differences are hours of learning, and you can switch later.
What to skip
- Skip building a proxy in your app. Writing request-forwarding logic in Express or Flask is slower, less secure, and reinvents solved problems. Let the proxy layer do it.
- Skip terminating TLS in multiple hops unless you have a real reason. Every extra decrypt/re-encrypt adds latency and a place for misconfiguration.
- Skip trusting
X-Forwarded-For blindly. Clients can forge it. Only trust it from proxies you control.
- Skip caching authenticated responses without care — a misconfigured cache can serve one user's private data to another. Verify your cache keys.
Throughput and certificate limits shift, so check the current docs for whatever tool you pick rather than trusting a blog's figures, including this one.
FAQ
Is a reverse proxy the same as a CDN?
No, but they overlap. A CDN is a globally distributed reverse-proxy-plus-cache network. A reverse proxy is the building block; a CDN is that block replicated close to users worldwide.
Do I need a reverse proxy for a small app?
Often yes, for one reason: free automatic HTTPS. Even a single-server hobby project benefits from Caddy handling certificates and redirects for you.
Does a reverse proxy slow things down?
Marginally at worst, usually the opposite: caching, connection reuse, and compression typically make the experience faster than hitting the backend directly.
Reverse proxy or API gateway?
Start with a reverse proxy. Reach for a dedicated API gateway only when heavy per-route auth, quotas, and versioning start to clutter the proxy config.
Where to go next
Understanding the edge is half the battle; the other half is what runs behind it. Choosing where to host that backend? Read AWS vs Azure in 2026. To lock down the services your proxy fronts, see API authentication explained for 2026. And since proxies live and die by concurrency, async and await explained for 2026 makes the code behind them click.