Skip to content
SeeItFlow
Interactive guide · 13 chapters · ~30 min read

Reverse Proxy Fundamentals

A reverse proxy sits between clients and your servers and does the jobs none of them should have to do individually — SSL termination, static file serving, routing, caching, and security. This guide builds it up incrementally: start from a client talking directly to an app, then add the proxy one problem at a time.

Mangesh MandlikLast updated:
01 · Foundations

What Is a Reverse Proxy? Nginx Reverse Proxy Basics

A reverse proxy is a server that sits in front of your application servers, receives every client request on their behalf, and forwards it to whichever backend should handle it — then relays the response back. Nginx is a common choice for the role, and the minimal configuration below shows the idea.

From the client's point of view, the reverse proxy is the application. The browser connects to one address, sends a request, and gets a response. It has no idea that behind that address there might be one app server or fifty, that the response came from a cache, or that a file was served straight from the proxy's own disk. That indirection is the whole point.

Swipe to pan
Clientone addressReverse ProxynginxApp 1app-1App 2app-2App 3app-3GET /
The canonical shape: many clients → one reverse proxy → the right one of several backend app servers.

The core responsibilities

Single public entry point

Clients only ever see the proxy's address. Backends can be added, removed, or relocated without any client noticing.

Request forwarding

Accept the client request, open its own connection to a backend, forward it, and relay the response — a full round-trip intermediary.

Edge responsibilities

Terminate SSL, serve static assets, route by path, cache responses, and block bad requests — once, at the edge, instead of in every app.

nginxThe minimal Nginx reverse proxy: accept requests and pass them upstream.
upstream app_servers {
  server 10.0.0.11:8080;
  server 10.0.0.12:8080;
}

server {
  listen 443 ssl;
  server_name example.com;
  ssl_certificate     /etc/ssl/example.com.pem;
  ssl_certificate_key /etc/ssl/example.com.key;

  location / {
    proxy_pass http://app_servers;   # forward to the backend pool
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
Interactive

Visual Learning

Watch one reverse proxy cluster absorb SSL termination, static files, path-based routing, caching, security, and load balancing in front of a backend fleet as a single continuous system — not eleven separate explanations.

02 · History & motivation

Why Reverse Proxies Exist

Every reverse proxy story starts the same way: a client talking directly to an application server, and that one server quietly being asked to do far too much.

Swipe to pan
ClientbrowserApp ServerSSL·static·routing·securitydirect connectionone server does everything
Direct access: one app server terminates SSL, serves static files, routes URLs, and faces the internet — all at once.

The direct-access pain

When a client hits your app directly, four problems appear almost immediately. First, every server manages its own TLS certificate — three servers means three renewal calendars and three ways to expire. Second, the app wastes CPU serving static files like images and stylesheets that never change. Third, every server is exposed to the internet, so each is a separate attack surface. Fourth, as you add an admin panel, an API, and a static site, routing logic gets tangled into each app or hardcoded into clients.

Key takeaways
  1. 01Direct access forces every app server to terminate SSL, serve static files, route, and defend itself.
  2. 02Those four concerns are cross-cutting — they belong in one shared layer, not copy-pasted per server.
  3. 03A reverse proxy is that layer, and it gives you one place to control the edge.
03 · The comparison people miss

Reverse Proxy vs Forward Proxy

The word "proxy" hides two opposite roles. The direction it faces is what makes it forward or reverse.

Swipe to pan
Forward proxyReverse proxyClientClientProxyInternetin front of clientsClientProxyApp 1App 2in front of servers
A forward proxy sits in front of clients and proxies their outbound traffic; a reverse proxy sits in front of servers and proxies inbound traffic on their behalf.

A forward proxy sits in front of a set of clients. When those clients want to reach the internet, they send their requests through the forward proxy — which can filter, log, cache, or anonymise the outbound traffic. A corporate web filter or a VPN egress is a forward proxy. It works on behalf of the client, and the destination server usually has no idea the proxy exists.

A reverse proxy sits in front of a set of servers. When clients out on the internet want to reach your application, they hit the reverse proxy, which forwards to the right backend. It works on behalf of the server, and the client usually has no idea the proxy exists. Same machinery, opposite direction, opposite beneficiary.

Forward proxy

In front of clients. Proxies outbound requests to the internet. The server doesn't know it's there. Used for filtering, egress control, client-side caching.

Reverse proxy

In front of servers. Proxies inbound requests to your backends. The client doesn't know it's there. Used for SSL, static, routing, caching, security.

04 · The comparison that matters

Reverse Proxy vs Load Balancer

A reverse proxy can load-balance across backends, but that is one capability inside a broader edge role. A load balancer's defining job is traffic distribution.

Swipe to pan
Load BalancerReverse ProxyLBspread onlyReplicaReplicaone narrow, fast jobProxySSL·cache·staticReplicaReplicaReplicaLB + many other jobs
A dedicated load balancer focuses on connection/request distribution; a reverse proxy forwards client HTTP(S) traffic and may also cache, terminate TLS, serve static files, and route by host or path.

A dedicated load balancer is built around backend selection: maintain a pool of healthy targets, choose where a new connection or request goes, and keep traffic flowing when a target fails. Some operate at L4, some at L7, and the richer ones add health-checked pools, stickiness, and distribution policies — but distribution is still the centre of gravity. See Load Balancer Fundamentals for the full mechanics.

A reverse proxy is the server-facing HTTP(S) entry point for an application. It terminates client connections, forwards them to one or more origins, and often adds TLS termination, compression, caching, static asset handling, and path/host routing. If several origins sit behind it, it can also balance across them — but that is a feature of the proxy, not its whole definition.

Load balancer

Primary job: choose a healthy backend for each connection or request. May run at L4 or L7 and is optimised for distribution and availability.

Reverse proxy

Primary job: be the application's public-facing intermediary. It forwards client HTTP(S) traffic to origin servers and can add TLS termination, routing, caching, compression, static delivery, and sometimes load balancing.

05 · The other comparison

Reverse Proxy vs API Gateway

An API gateway is usually built on reverse-proxy technology, but tuned for API-specific policy rather than general web edge duties.

A reverse proxy handles transport and HTTP-level concerns for whatever sits behind it: terminate TLS, compress responses, cache safe content, serve static assets, and route by host or path to one or more backends. It is a general-purpose edge intermediary for web traffic, not just a one-service fan-out box.

An API gateway takes that proxy foundation and adds API-facing concerns such as authentication, authorization, per-consumer rate limiting, request/response transformation, aggregation, and versioning. So the boundary is not "proxy" versus "gateway" as unrelated categories; it is general HTTP edge proxying versus API product policy. See API Gateway Fundamentals for the API-specific layer.

Reverse proxy

General HTTP(S) front door for backends. Strong at TLS termination, routing, caching, compression, static delivery, and hiding origins behind one public entry point.

API gateway

A reverse-proxy-based API front door that adds auth, quotas, transformations, aggregation, versioning, and other API-consumer policy.

06 · How it works

The Request Lifecycle Through a Reverse Proxy

One request through a reverse proxy is really two connections and four hops, with the proxy as the pivot in the middle.

Swipe to pan
ClientReverse ProxyBackend1 · request2 · forward3 · response4 · relay
Client → Proxy → Backend on the way in; Backend → Proxy → Client on the way out. Two independent connections.

The client opens a connection to the proxy and sends its request — hop one. The proxy opens its own, separate connection to a backend and forwards the request — hop two. The backend does the real work and replies to the proxy — hop three. The proxy relays that response down the client-side connection — hop four.

The two-connection design is what unlocks everything else. Because the client-side and backend-side connections are independent, the proxy can terminate TLS on one side and speak plain HTTP on the other, pool and reuse backend connections, buffer slow clients, and swap which backend it talks to without the client ever reconnecting.

07 · Job one

SSL / TLS Termination

HTTPS has to be decrypted somewhere. Doing it once at the proxy instead of on every backend is one of the biggest operational wins a reverse proxy gives you.

Swipe to pan
Before · cert per backendAfter · terminate onceClient🔒 App 1🔒 App 2🔒 App 3Client🔒 ProxyAppApphttpsplain http
Before: every backend holds a certificate. After: HTTPS terminates at the proxy; the backend hop is either plain HTTP on a trusted network or HTTPS again if you re-encrypt internally.

With TLS termination (often called TLS offload), the client completes the TLS handshake with the reverse proxy. The public certificate and private key live on that proxy tier, so it is the component that decrypts the request and gains full L7 visibility for routing, caching, compression, WAF rules, and logging.

From the proxy inward you choose the trust model. In many deployments the proxy forwards plain HTTP across a private network to simplify backend operations and remove handshake CPU from app servers. In stricter environments the proxy terminates public TLS and then opens a new HTTPS or mTLS connection to the backend, preserving encryption on the internal hop too.

The operational payoff is still the same: certificate lifecycle, TLS versions, cipher policy, OCSP stapling, and renewals are centralised on the edge tier instead of repeated on every origin server. Pure TCP pass-through is different — the proxy never decrypts, so the backend keeps the cert and the proxy loses most HTTP-aware features.

08 · Job two

Static Asset Delivery

A huge fraction of web traffic is static files that never change per request. Making your application generate them is a waste — the proxy can serve them itself.

Swipe to pan
Clientlogo·js·cssReverse Proxyserves staticApp Serveridle for staticGET /logo.pngserved from diskbypassed
Static requests (logo.png, app.js, style.css) are served or cached at the proxy; the app server is bypassed entirely and left for dynamic work.

When a request for /logo.png arrives, the proxy matches it against its static rules, finds the file on its own disk, and returns it — the application server is never contacted. A compiled proxy like Nginx serving a file from disk is dramatically faster and cheaper than a language runtime doing the same thing.

The effect on backend load is immediate. All that repetitive static traffic is absorbed at the edge, leaving the application free to spend its CPU on the dynamic requests only it can compute. Splitting static from dynamic at the proxy is often the single biggest reason teams put Nginx in front of an app.

nginxServe static files from disk; forward everything else to the app.
location /static/ {
  root /var/www;            # served directly from the proxy
  expires 30d;             # let browsers cache too
}

location / {
  proxy_pass http://app_servers;   # dynamic → backend
}
09 · Job three

Routing (Path-Based)

A real site is rarely one app. The proxy can front several services behind one domain and route each request by its URL path.

Swipe to pan
ClientReverse Proxyroute by pathAPI/apiAdmin/adminStatic/staticGET /api/orders
One proxy, one domain, three destinations: /api → API service, /admin → Admin, /static → assets.

The proxy inspects each request's path and forwards it to the backend that owns that prefix — /api/* to the API service, /admin to the admin panel, /static/* to the assets. To the outside world it is a single, coherent site; behind the proxy it is several independent services that can be deployed, scaled, and owned by different teams.

nginxPath-based routing excerpt (assumes `api_service`, `admin_service` and `asset_service` upstream blocks are defined like `app_servers` above). Here `/static` is proxied to an asset service; the previous section serves it from local disk instead — pick one per deployment.
location /api/   { proxy_pass http://api_service; }
location /admin  { proxy_pass http://admin_service; }
location /static { proxy_pass http://asset_service; }
10 · Job four

Caching

If ten thousand people ask for the same page in a minute, why regenerate it ten thousand times? The proxy can remember the response and hand out copies.

Swipe to pan
Visitor AmissVisitor BhitProxycachecache · TTL 60sApp Servermiss → backendhit → served
A cache miss falls through to the backend and populates the proxy cache; a later hit is served from the reverse proxy itself, backend untouched.

On a cache miss the proxy has nothing stored, so it forwards to the backend, then keeps a copy of the response tagged with a time-to-live before sending it on. On a subsequent cache hit, while that copy is still fresh, the proxy answers immediately and the backend is never touched. Reverse proxies really do cache responses themselves — for example, Nginx can do this with proxy_cache; caching is not unique to CDNs.

Hit ratio is the whole game. At a 90% hit ratio your backend sees a tenth of the traffic and users get near-instant responses. A reverse-proxy cache usually lives in one deployment or region; a CDN applies the same idea across many geographically distributed edge locations. The classic mistake is caching content that shouldn't be shared — per-user or rapidly-changing data — so caching is always about choosing what is safe to cache and for how long.

11 · Job five

Security

Because the proxy is the only thing exposed to the internet, it is the perfect place to defend the whole system.

The backends sit on a private network with no public address, so nobody outside can even attempt to reach them — only the proxy can. Hiding the internal topology matters: an attacker cannot target a box they cannot see or address.

Because every request flows through it, the proxy is also the natural place to inspect and reject bad traffic. It can block known exploit patterns, enforce IP allow-lists, apply connection and request rate limits, and add security headers — dropping hostile requests at the edge before they ever reach an application that would have to parse them. API gateways may still add per-consumer quotas or auth policy, but coarse perimeter filtering belongs naturally at the reverse proxy.

12 · Staying up

High Availability & Scaling

A single proxy sits on every request, which makes it a single point of failure. At scale you run several and put a load balancer in front of them.

If everything routes through one proxy and it dies, the whole site goes dark — no SSL, no routing, no cache. The fix is to run multiple identical proxy instances as a cluster and place a dedicated load balancer in front, spreading traffic across them and health-checking each one. If a proxy fails, the load balancer simply stops sending it traffic and users never notice.

Each layer scales independently and horizontally. Under load you add proxy instances; the backends scale on their own axis. Because proxies are mostly stateless (cache aside), adding or removing one is cheap.

13 · The whole picture

Production Architecture

Put every piece together and you get the shape behind most large web systems.

Swipe to pan
InternetLBhealth-checkedProxy 1nginxProxy 2nginxProxy 3✗ failedApp 1App 2no single point of failure
Internet → Load Balancer → Reverse Proxy Cluster → Backend Services. Each layer has one job and scales on its own.

Traffic from the internet often hits a CDN or dedicated load balancer first, which then spreads it across a resilient tier of reverse proxies. That proxy tier terminates TLS, serves static files, caches responses, routes by path, and filters hostile traffic — then forwards the surviving dynamic requests to the backend services. Every layer is independently scalable and is designed so that none is a single point of failure.

Key takeaways
  1. 01A reverse proxy is the smart, HA edge tier in front of your services.
  2. 02It bundles SSL termination, static serving, routing, caching, and security into one layer.
  3. 03In production you front a proxy cluster with a load balancer and hide the backends on a private network.
  4. 04Learn it as an evolution: start from direct access, then add each job one problem at a time.