A reverse proxy is a server that accepts requests from clients on behalf of one or more backend servers, forwards each request to an appropriate backend and returns the response as if it had produced it itself. In web servers, the reverse proxy is the public entry point of an application: clients see only the proxy’s address, while the application servers stay hidden on a private network or on local ports.
The reverse proxy is the mirror image of a forward proxy. A forward proxy acts for clients that reach out to the internet; a reverse proxy acts for servers that receive traffic from the internet. Nginx, Apache with mod_proxy, Caddy, HAProxy and many load balancers and CDNs all perform this role.
How a reverse proxy handles a request
A reverse proxy terminates the client’s connection, inspects the request and opens a separate connection to the chosen backend. The proxy therefore manages two independent connections per request: the client side, often HTTPS over HTTP/2 or HTTP/3, and the upstream side, often plain HTTP/1.1 on a private network or a Unix socket.
Routing decisions are based on the host name, URL path, headers or cookies. A single proxy can send /api/ to an application server such as Gunicorn, static files to local disk and the rest of the site to a PHP-FPM pool. Before forwarding, the proxy typically adds headers such as X-Forwarded-For, X-Forwarded-Proto or the standardized Forwarded header, so the backend knows the original client address and protocol.
On the way back, the proxy can rewrite headers, compress responses and cache them. Because it buffers responses from the backend, a slow client on a mobile connection does not hold an expensive application worker busy for the entire transfer.
Main functions of a reverse proxy
A reverse proxy concentrates several cross-cutting tasks in one place, which keeps application servers simpler. The table lists the functions most deployments use and what each achieves.
| Function | What the proxy does | Benefit |
|---|---|---|
| TLS termination | Decrypts HTTPS and manages certificates | One place for certificates and protocols |
| Load balancing | Distributes requests across backends | Scale-out and failover |
| Caching | Stores and reuses cacheable responses | Lower backend load and latency |
| Compression | Applies gzip or Brotli to responses | Less bandwidth, faster pages |
| Security filtering | Rate limits, blocks paths, adds a WAF | Protection before requests reach the app |
| Routing and consolidation | Maps hosts and paths to services | Many apps behind one IP and port 443 |
Not every deployment uses every function. A small site may only need TLS termination and routing, while a high-traffic platform combines caching, load balancing and a web application firewall at the same layer.
Load balancing methods behind a reverse proxy
When a reverse proxy has several backends for the same service, it needs a balancing method and a way to detect failed servers. The method should match the workload, because the wrong choice can overload one backend while others idle.
| Method | How it chooses a backend | Suitable for |
|---|---|---|
| Round robin | Each backend in turn, optionally weighted | Similar servers, short uniform requests |
| Least connections | Backend with fewest active connections | Requests of varying duration |
| IP hash | Hash of the client address | Simple session affinity |
| Cookie-based affinity | Sticky cookie set by the proxy | Applications with local session state |
| Random with two choices | Better of two random backends | Large pools with many proxies |
Health checks complete the picture. Passive checks mark a backend as failed after errors or timeouts on real traffic; active checks send periodic test requests. Without them, the proxy keeps sending users to a server that no longer answers.
Reverse proxy compared with related components
Several components overlap with the reverse proxy, and the boundaries are often blurred in products. The comparison helps to place them correctly.
| Component | Acts on behalf of | Typical layer | Main purpose |
|---|---|---|---|
| Forward proxy | Clients | HTTP or SOCKS | Control and cache outbound access |
| Reverse proxy | Servers | HTTP, layer 7 | Front door for web applications |
| Layer 4 load balancer | Servers | TCP or UDP | Distribute connections without reading HTTP |
| API gateway | Servers, for APIs | HTTP, layer 7 | Authentication, quotas, API routing |
| CDN | Origin servers | HTTP, distributed edge | Serve cached content close to users |
An API gateway and a CDN are both specialized reverse proxies. The difference lies in focus and deployment: the gateway adds API management features, and the CDN runs reverse proxies in many locations worldwide.
Configuring a reverse proxy safely
Most reverse proxy problems are configuration errors that appear only under specific conditions. The recurring ones are these:
- Trusting forwarded headers blindly: the backend must accept
X-Forwarded-Foronly from the proxy, or clients can spoof their address. - Wrong scheme detection: an application that does not see
X-Forwarded-Protogenerates HTTP links or redirect loops behind an HTTPS proxy. - Caching personalized pages: missing
Cache-Controlor cookie rules can serve one user’s page to another. - Mismatched timeouts and body limits: long uploads or slow reports fail with 504 or 413 errors at the proxy.
- Exposed backends: application ports left open to the internet bypass every protection the proxy adds.
WebSocket and streaming connections also need explicit upgrade and buffering settings. Testing these paths, along with logs that include the upstream response time, makes it clear whether a slow request is caused by the proxy or by the application.
Put simply
A reverse proxy is the receptionist in front of a website’s servers. Visitors talk only to the receptionist, who passes each request to the right person in the back office and brings the answer back.
Because everything goes through this one desk, it can also check visitors, hand out ready answers to common questions and spread work fairly among the staff. The servers behind it stay hidden and protected, and the site can grow without visitors noticing any change.
In practice
An online booking platform runs a Python application on three backend servers, each with Gunicorn listening on a private address. In front of them, two Nginx instances act as reverse proxies on a shared virtual IP address, terminating HTTPS with automatically renewed certificates and balancing requests with the least connections method.
Static images and stylesheets are served directly by Nginx and cached for a day, which removes most of the request volume from the application servers. When one backend is taken offline for an upgrade, active health checks remove it within seconds, and customers continue booking without errors while the team deploys the new version server by server.