> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reverse Proxy

> Explains reverse proxies, NGINX features like SSL termination, load balancing, caching, routing, and practical configuration examples for production deployments

Welcome back.

In this lesson we expand on reverse proxies: what they are, the common features you’ll see in production (SSL/TLS termination, load distribution, caching), and how NGINX implements these patterns.

What is a reverse proxy?

* A reverse proxy sits between clients and backend servers. It accepts client requests, forwards them to one or more backend servers (an upstream pool), and returns the backend response to the client.
* It abstracts and protects backend servers while adding features such as routing, SSL termination, caching, header injection, and access control.

For illustration below I show multiple backend servers. In real deployments you’ll most commonly see homogeneous backend pools (for example, three identical app servers), but this diagram highlights that a reverse proxy can forward traffic to different kinds of servers.

![A diagram titled "Reverse Proxy vs Load Balancer" showing clients sending requests to a Load Balancer. The Load Balancer evenly distributes traffic to multiple backend servers labeled Server 1–4.](https://mintcdn.com/kodekloud-c4ac6d9a/ij3FNIPjp1w0Myd0/images/Nginx-for-Beginners/Intermediate-Config/Reverse-Proxy/reverse-proxy-vs-load-balancer-diagram.jpg?fit=max\&auto=format\&n=ij3FNIPjp1w0Myd0\&q=85\&s=bdb0d33141048fdfd06467732f6bbe61)

Reverse proxy vs load balancer

* The two concepts overlap, which often causes confusion. Use the table below to clarify the distinction and when each term is most appropriate.

| Role | Primary responsibility | Typical features / examples |
| - | - | - |
| Reverse proxy | Intermediary between client and server; hides backend details and introduces features | Routing, SSL/TLS termination, header management, caching |
| Load balancer | Distribute requests across multiple backend servers to balance load and improve availability | Round-robin, least connections, health checks, session affinity |

A single NGINX instance can act as a reverse proxy, a load balancer, or both — the behavior depends on how you configure upstreams, proxying, and load-balancing directives.

Why put application frameworks behind a reverse proxy?

* Frameworks (React, Flask, Rails, Laravel, etc.) bind to a local port during development (e.g., React on 3000, Flask on 5000). In production, you typically place these services behind a reverse proxy:
  * Centralized TLS certificate management
  * Consistent routing and URL canonicalization
  * Better protection: backend services are not directly exposed to the internet
  * Easier to add caching, compression, and rate limiting

![Two browser windows showing local development sites: on the left a React app with the React logo and the "Edit src/App.js and save to reload" message, and on the right a Flask webpage titled "Welcome to Flask."](https://mintcdn.com/kodekloud-c4ac6d9a/ij3FNIPjp1w0Myd0/images/Nginx-for-Beginners/Intermediate-Config/Reverse-Proxy/react-flask-local-dev-windows.jpg?fit=max\&auto=format\&n=ij3FNIPjp1w0Myd0\&q=85\&s=46b8b2fff689bfa35a76fcdc1609b995)

Common reverse-proxy use cases

* SSL/TLS termination: offload cryptographic work to the proxy and forward unencrypted HTTP to internal backends.
* Load distribution: balance traffic across multiple backend servers for capacity and redundancy.
* Caching: reduce repeated backend work for static assets and cacheable responses.
* Routing and virtual hosting: serve multiple domains or applications from a single entrypoint.
* Security and headers: inject or strip headers, enforce access controls, and perform rate limiting.

SSL/TLS termination (typical configuration)

* Terminating TLS at the proxy reduces CPU usage on backend servers and centralizes certificate management. The example below shows an upstream pool and an HTTP server block that proxies to that pool, then an HTTPS server block that terminates TLS.

Simple upstream + HTTP proxying:

```nginx theme={null}
http {
    upstream backend {
        server 10.10.0.101:80;
        server 10.10.0.102:80;
        server 10.10.0.103:80;
    }

    server {
        listen 80;
        server_name example.com www.example.com;

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

Terminate TLS at the proxy and forward HTTP to backends:

```nginx theme={null}
http {
    upstream backend {
        server 10.10.0.101:80;
        server 10.10.0.102:80;
        server 10.10.0.103:80;
    }

    server {
        listen 443 ssl;
        server_name example.com www.example.com;

        ssl_certificate     /etc/nginx/ssl/server.crt;
        ssl_certificate_key /etc/nginx/ssl/server.key;
        ssl_protocols       TLSv1.2 TLSv1.3;

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

When you need full end-to-end TLS

* For compliance or security reasons you may require TLS between the proxy and the backend as well. Key points:
  * Define upstream servers that listen on port 443 (or the appropriate TLS port).
  * Use `proxy_pass https://backend/;` to forward via HTTPS.
  * Configure trust between proxy and backends (client certs, CA bundles) so the proxy can validate backend certificates.
  * Ensure backend servers have valid certificates (self-signed can be used with appropriate trust configuration).

Caching to reduce backend load

* Without caching, the reverse proxy will request static assets, HTML, and other resources from the backend on every client request. NGINX can cache responses to reduce backend load and lower latency for repeated requests.

![A diagram titled "No Cache" showing an NGINX load balancer routing traffic through a central load-balancing component to multiple web servers. The web servers are depicted serving media, HTML pages, and backend data.](https://mintcdn.com/kodekloud-c4ac6d9a/ij3FNIPjp1w0Myd0/images/Nginx-for-Beginners/Intermediate-Config/Reverse-Proxy/nginx-no-cache-loadbalancer-web-servers.jpg?fit=max\&auto=format\&n=ij3FNIPjp1w0Myd0\&q=85\&s=b9adc43bfec6a82abedb01c6995e2f83)

Basic cache configuration (simplified)

* This example shows the main pieces: cache path, key, TTLs, and how to enable the cache in a location. Cache tuning (eviction, size, levels) is important for production but beyond this lesson.

```nginx theme={null}
http {
    proxy_cache_path /var/lib/nginx/cache levels=1:2 zone=app_cache:8m;
    proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;

    server {
        listen 80;
        server_name example.com www.example.com;

        location / {
            proxy_cache app_cache;
            proxy_cache_bypass $http_cache_control;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://backend/;
        }
    }
}
```

Caching directives at a glance

| Directive | Purpose | Notes |
| - | - | - |
| `proxy_cache_path` | Define cache storage, hierarchy, and zone name | Example: `proxy_cache_path /var/lib/nginx/cache levels=1:2 zone=app_cache:8m;` |
| `proxy_cache_key` | Compose the cache key used to identify cached responses | Include elements that affect content, such as host, query string, and method |
| `proxy_cache_valid` | Set TTLs for cached responses by status code | Example: `proxy_cache_valid 200 302 10m;` |
| `proxy_cache_bypass` | Conditions to skip the cache (headers, cookies, etc.) | Useful for honoring `Cache-Control` or bypassing cache for logged-in users |

Further resources

* NGINX docs: [https://nginx.org/en/docs/](https://nginx.org/en/docs/)
* TLS best practices: [https://www.ietf.org/](https://www.ietf.org/)
* Let’s Encrypt (free TLS certificates): [https://letsencrypt.org/](https://letsencrypt.org/)

That concludes this lesson. Next we’ll demo configuring these reverse-proxy features in NGINX, and dive into cache tuning, header manipulation, and additional performance options.

> **[Watch Video](https://learn.kodekloud.com/user/courses/nginx-for-beginners/module/c78ff9cb-c15d-4f85-92fc-abee5ed98b20/lesson/beb4a7aa-77e5-4e9b-9d41-4a3f7029a73a)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.