Hello! Welcome to the fourth lesson in our module on Web Servers and Application Runtimes.
In our last lesson, we explored the different worker models that servers use to handle concurrency: pre-fork, threaded, and event-driven. We concluded by seeing how a typical production setup for a Django application uses a hybrid model: the event-driven Nginx server acts as a gateway for the pre-fork Gunicorn application server.
We mentioned that in this setup, Nginx is acting as a reverse proxy. This is a fundamental pattern in backend architecture. Today's lesson is dedicated to formally understanding it. Our goal is to explain the purpose of a reverse proxy and its common use cases, specifically load balancing and SSL termination.
Mastering this concept is crucial because reverse proxies are the front door to almost every scalable web service. They are the component that allows a small application to grow into a system that can handle millions of users.
What is a Reverse Proxy?
At its core, a proxy is an intermediary. It sits between two parties and forwards communication. There are two main types, and the difference is all about who the proxy is serving.
- Forward Proxy: Sits in front of a client or a group of clients (e.g., within a corporate network). It forwards their outgoing requests to the internet. From the perspective of a web server on the internet, all requests from behind the forward proxy appear to come from the proxy itself. It acts on behalf of the client.
- Reverse Proxy: Sits in front of a server or a group of servers. It receives incoming requests from clients on the internet and forwards them to the appropriate backend server. From the client's perspective, they are communicating directly with the reverse proxy; the backend servers are completely hidden. It acts on behalf of the server.
Throughout this course, when we talk about proxies in a backend context, we are almost always talking about reverse proxies.
To get a quick and clear overview of this concept and its primary benefits, let's start with a short video.
Proxy vs Reverse Proxy (Real-world Examples)
The ByteByteGo channel provides excellent, concise explanations of system design concepts. This video will introduce the reverse proxy and its main benefits in just a few minutes.
Please watch the video from 02:21 to 04:19. Focus on how the reverse proxy: Acts as an intermediary between the internet and the web servers. Protects backend servers by hiding their IP addresses. Distributes traffic across multiple servers (load balancing). Handles expensive SSL encryption operations.
Key Use Cases of a Reverse Proxy
As the video highlighted, a reverse proxy isn't just a simple forwarder; it's a powerful, multi-purpose tool. Let's break down its most important roles, which directly address our learning outcome.
For a comprehensive reading on these use cases, the following article provides an excellent breakdown.
Proxy vs Reverse Proxy vs Load Balancer: Complete Guide
This article from CodeWiz Info provides a detailed look at the common applications of a reverse proxy. We'll refer to it for several concepts in this lesson.
Please read the sections titled 'What is a Reverse Proxy?' and 'Common Use Cases for Reverse Proxies'. As you read, pay close attention to the explanations for: Load distribution (which we'll call load balancing). SSL termination. Performance optimization (caching and compression). Security (acting as a protective barrier).
Let's dissect the two most critical use cases mentioned in our learning outcome.
1. Load Balancing
A single application server can only handle a finite amount of traffic. Once it reaches its limit, performance degrades, and it eventually fails. This creates a bottleneck and a single point of failure.
Load balancing is the solution. Instead of one powerful server, you run multiple smaller, identical instances of your application server. The reverse proxy then acts as a "traffic cop," distributing incoming requests across this pool of servers.
This provides two major benefits:
- Scalability: When traffic increases, you can simply add more application servers to the pool. The reverse proxy will automatically start sending requests to them. This is the essence of horizontal scaling.
- High Availability: If one of your application servers crashes or needs to be taken offline for maintenance, the reverse proxy can detect this (using health checks) and stop sending traffic to it. The remaining servers continue to handle requests, and users experience no downtime.
2. SSL/TLS Termination
In the HTTPS module, we learned that establishing a secure connection involves a TLS handshake, which uses public-key cryptography and is computationally expensive.
Forcing every one of your backend application servers to handle this encryption and decryption is inefficient. It wastes CPU cycles that could be better spent running your application code. Furthermore, managing SSL certificates (installing, renewing, and securing them) across dozens or hundreds of servers is a significant operational burden.
SSL/TLS Termination is the process of offloading this work to the reverse proxy.
The architecture looks like this:
- The client establishes a secure HTTPS connection with the reverse proxy.
- The reverse proxy decrypts the incoming request. We say it has "terminated" the SSL connection.
- The reverse proxy forwards the now-unencrypted request to the appropriate backend server over a secure, private internal network using plain HTTP.
- The backend server processes the request and sends an HTTP response back to the proxy.
- The proxy encrypts the response and sends it back to the client via HTTPS.

The benefits are clear:
- Improved Performance: Your application servers are freed from the computational overhead of cryptography.
- Simplified Certificate Management: You only need to manage one SSL certificate on the reverse proxy, not on every backend server.
Reverse Proxy vs. Load Balancer: What's the Difference?
You may have noticed that the terms "reverse proxy" and "load balancer" are often used interchangeably. This can be confusing. Let's clarify the relationship.
- A reverse proxy is a general-purpose server that forwards traffic on behalf of other servers.
- A load balancer is a specialized type of reverse proxy whose primary function is to distribute traffic across multiple servers.
Therefore, all load balancers are reverse proxies, but not all reverse proxies are load balancers. You could have a reverse proxy sitting in front of a single backend server just to provide SSL termination, caching, or an extra layer of security.
The following video provides an excellent, in-depth explanation of this nuance.
Load Balancer vs Reverse Proxy (Explained by Example)
Hussein Nasser's channel is known for its deep dives into backend engineering topics. In this video, he clarifies the relationship between reverse proxies and load balancers.
Watch the segment from 05:49 to 09:16. Focus on: His definition of a load balancer as an 'instance' or specific application of a reverse proxy. The idea that a load balancer must have two or more backend servers, while a reverse proxy can have just one. The different load balancing algorithms he mentions (round-robin vs. 'smart' balancing).
To reinforce this, the "Comparison Table" in the CodeWiz article you read earlier is a great summary of the feature differences.
A Practical Look: Nginx Configuration
Let's see how these concepts translate into a real Nginx configuration. The following snippet shows Nginx configured as a reverse proxy that both terminates SSL and load balances requests to a pool of three backend servers.
# 1. Define the pool of backend application servers.
# Nginx will distribute requests among these.
upstream backend_servers {
# The 'least_conn' directive tells Nginx to send requests
# to the server with the fewest active connections.
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
# 2. Listen for incoming HTTPS traffic on port 443.
listen 443 ssl;
server_name api.example.com;
# 3. Specify the SSL certificate and key for SSL termination.
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
# 4. Forward the decrypted request to the 'backend_servers' upstream group.
# This is where the reverse proxy and load balancing happens.
proxy_pass http://backend_servers;
# These headers pass along information about the original request
# to the backend servers, which now only see requests from the proxy.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
This configuration elegantly combines everything we've discussed:
- The
upstreamblock defines our application server pool for load balancing. - The
listen 443 sslandssl_certificatedirectives handle the SSL termination. - The
proxy_passdirective is the core of the reverse proxy function, forwarding the request to the upstream group.
Conclusion
You now understand the critical role of a reverse proxy in modern backend architecture. It's not just a simple passthrough; it's an intelligent gateway that provides scalability, security, and performance enhancements.
Key Takeaways:
- A reverse proxy sits in front of backend servers, hiding them from clients and forwarding requests on their behalf.
- Load balancing is a key use case where a reverse proxy distributes traffic across multiple application servers, enabling scalability and high availability.
- SSL termination is another critical function, where the proxy handles expensive encryption/decryption tasks, offloading work from backend servers and centralizing certificate management.
- Other important uses include caching static content, providing a unified security checkpoint (rate limiting, WAF), and enabling advanced deployment strategies like canary releases.
- A load balancer is a specialized type of reverse proxy.
Preview of the Next Lesson:
In our Nginx example, the proxy_pass http://backend_servers; directive seamlessly forwards the request. But how does Nginx know how to communicate with a Python application server like Gunicorn in a standardized way? In the next lesson, we will explore the WSGI and ASGI specifications and how they bridge a web server to a Python application. This is the "glue" that connects the two tiers of our backend stack.