DEV Community

Mathew
Mathew

Posted on

Forward Proxy vs Reverse Proxy: A Developer's Guide to the Difference

"Proxy" is one of those terms that means different things depending on who's using it and in what context. An infrastructure engineer reaching for Nginx to handle load balancing is talking about a reverse proxy. A developer configuring a scraper to route traffic through residential IPs is talking about a forward proxy. Both are proxies in the general sense - an intermediary that sits between two parties in a network connection - but they solve opposite problems and sit on opposite sides of the client-server relationship.
The confusion compounds because tools like Nginx and HAProxy can operate as either, depending on configuration, and some systems use both simultaneously. This guide draws a clear line between the two, explains the architectural role each plays, and covers the concrete use cases where each type is the right tool.
The Core Distinction: Who the Proxy Serves
The simplest way to understand the difference is to ask who the proxy is working for.
A forward proxy works on behalf of the client. It sits between a client (your browser, your scraper, your application) and the internet. When the client wants to reach a server, the request goes to the forward proxy first, which forwards it to the destination. The destination server sees the proxy's IP address, not the client's. The client is the party being served - their identity is hidden, their traffic is routed, their requests are filtered or modified on the way out.
A reverse proxy works on behalf of the server. It sits between the internet and one or more origin servers. When a client makes a request, it hits the reverse proxy first, which decides how to handle it - which backend server to forward it to, whether to serve a cached response, whether to terminate TLS, whether to apply rate limiting. The client has no visibility into the origin server. The server infrastructure is the party being served - its identity is hidden, its load is distributed, its traffic is managed on the way in.
Same intermediary pattern, opposite orientation. Forward proxy = client-side. Reverse proxy = server-side.
Forward Proxy: Architecture and Use Cases
A forward proxy is explicitly configured by the client (or the network the client is on). The client knows it's using a proxy - it sends its requests to the proxy address rather than directly to the destination.
How it works:
Client → Forward Proxy → Internet → Destination Server

The client sends a request to the proxy. The proxy forwards it to the destination on the client's behalf. The destination returns the response to the proxy, which passes it back to the client. From the destination's perspective, the request originated from the proxy IP.
For HTTP/HTTPS traffic, forward proxies typically use one of two mechanisms. For HTTP, the proxy reads the full request and forwards it. For HTTPS, the proxy uses the CONNECT method to establish a tunnel - the client tells the proxy "connect me to host:port" and the proxy opens a TCP tunnel, after which the client and destination communicate directly through the tunnel (with the proxy passing bytes without inspecting them).
Common use cases:
Corporate network filtering is one of the oldest forward proxy use cases. Traffic from employees' machines routes through a proxy that enforces content policies, logs traffic for compliance, and blocks access to unauthorized sites. The proxy is transparent to users on the corporate network but explicitly configured in the browser or OS network settings.
Privacy and IP masking are what most developers think of when they hear "proxy." Routing requests through a proxy hides the client's real IP from the destination. The destination sees the proxy's IP, not the requester's. This is the pattern used by residential and mobile proxy services for scraping, ad verification, account management, and geo-restricted content access - a full overview of how this applies in practice is covered in the NodeMaven proxy guide.
Caching is another forward proxy use case - a shared proxy can cache responses from frequently requested destinations, reducing bandwidth consumption for networks with many clients hitting the same external resources. This was a significant use case in the early web when bandwidth was expensive; it's less common now but still relevant in high-latency or bandwidth-constrained environments.
Access control and geo-restriction bypass both use the same mechanism. A forward proxy in a specific geographic location allows clients anywhere to make requests that appear to originate from that location.
Forward proxy in code:
import requests

Configure a forward proxy for a single request
proxies = {
"http": "http://user:pass@proxy-host:8080",
"https": "http://user:pass@proxy-host:8080"
}

response = requests.get("https://example.com", proxies=proxies)

curl with a forward proxy
curl --proxy http://user:pass@proxy-host:8080 https://example.com

Environment variable (applies to many tools automatically)
export HTTPS_PROXY="http://user:pass@proxy-host:8080"
curl https://example.com

Reverse Proxy: Architecture and Use Cases
A reverse proxy is configured on the server side and is invisible to the client. The client believes it's communicating directly with the application server - it has no awareness that its request is being handled by an intermediary.
How it works:
Client → Reverse Proxy → Origin Server(s)

The client sends a request to what it believes is the application server (say, api.example.com). That DNS name resolves to the reverse proxy's IP. The proxy receives the request, applies its configured logic (routing, caching, rate limiting, TLS termination), and forwards the request to the appropriate backend. The response returns through the same path.
Common use cases:
Load balancing is the most common reverse proxy use case in production systems. A single reverse proxy distributes incoming requests across multiple backend instances, ensuring no single server is overwhelmed and providing redundancy when servers fail. Nginx, HAProxy, and cloud load balancers (AWS ALB, GCP Load Balancing) all operate in this mode.
Nginx reverse proxy with load balancing
upstream backend {
server app1.internal:8000 weight=3;
server app2.internal:8000 weight=3;
server app3.internal:8000 weight=1; less powerful instance
}

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

location / {
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Enter fullscreen mode Exit fullscreen mode

}

TLS termination is handled at the reverse proxy layer in most production architectures. The proxy accepts HTTPS connections from clients (handling the TLS handshake and certificate management), then forwards requests to backend servers over plain HTTP on the internal network. This centralizes certificate management and offloads TLS processing from application servers.
server {
listen 443 ssl;
server_name api.example.com;

ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;

location / {
    proxy_pass http://backend;   plain HTTP to backend
    proxy_set_header X-Forwarded-Proto https;
}
Enter fullscreen mode Exit fullscreen mode

}

Caching at the reverse proxy layer serves static assets and cacheable API responses without hitting the origin server. CDNs (Cloudflare, Fastly, AWS CloudFront) are distributed reverse proxies with global caching infrastructure - a request for a static asset gets served from the CDN edge node nearest the client rather than traveling to the origin.
Security and DDoS protection are handled at the reverse proxy layer in most internet-facing architectures. The origin server's IP is hidden - clients only know the reverse proxy's address. Rate limiting, bot detection, WAF (Web Application Firewall) rules, and request validation all run at the proxy layer before traffic reaches the application.
Rate limiting at the reverse proxy
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}

API gateway functionality - routing different URL paths to different backend services, transforming requests and responses, handling authentication - is commonly implemented as a reverse proxy configuration. Tools like Kong, Traefik, and AWS API Gateway are specialized reverse proxies built for this purpose.
Where They Overlap: The Transparent Proxy
There's a third category that blurs the forward/reverse distinction: the transparent proxy. A transparent proxy intercepts network traffic without explicit client configuration - the client doesn't know it exists. From the client's perspective, it's communicating directly with the destination. From the network's perspective, all traffic passes through the proxy.
ISPs sometimes use transparent proxies for caching and traffic management. Corporate networks use them for content filtering when they don't want users to be able to bypass the proxy by removing browser settings. Router-level DNS redirect rules (intercepting port 53 traffic as described in router-level DNS configuration guides) are a form of transparent proxying for DNS specifically.
The key difference from a forward proxy: the client doesn't configure or acknowledge the transparent proxy. The key difference from a reverse proxy: the transparent proxy is serving the network operator's interests, not the destination server's.
Choosing Between Them in System Design
In practice, the choice isn't usually forward or reverse - most non-trivial architectures use both simultaneously.
A user's browser might be configured to use a forward proxy (corporate network, VPN, residential proxy service) when it sends a request. That request hits the internet and reaches a reverse proxy (Nginx, CDN edge, API gateway) in front of the application. Both proxies are active in the same request path, serving different parties.
The design question is which layer to add a proxy at and for what purpose. Forward proxy when you need to control outbound traffic from clients - masking origin, routing through specific geographic IPs, applying corporate policies, caching shared external resources. Reverse proxy when you need to control inbound traffic to servers - distributing load, terminating TLS, caching responses, protecting origin servers, routing requests to microservices.
The confusion between the two usually comes from the word "proxy" appearing in both contexts without qualification. Adding "forward" or "reverse" to the conversation immediately clarifies which pattern is being discussed - and in most system design conversations, the qualifier is what tells you which problem is actually being solved.
A Quick Reference
Forward proxy: client-side, client-configured, hides client identity, routes outbound requests. Reverse proxy: server-side, server-configured, hides server identity, manages inbound requests. Transparent proxy: neither client nor server-configured, intercepts traffic at the network level.
Same underlying mechanism - an intermediary that forwards requests between two parties - oriented in different directions for different purposes.

Top comments (0)