Reverse Proxy Architecture — SSL Termination, Caching, and Load Balancing Explained
What is a reverse proxy?#
A reverse proxy sits between clients and your backend servers. Clients send requests to the proxy, the proxy forwards them to one or more origin servers, and then relays the response back. The client never communicates directly with the backend.
This is the opposite of a forward proxy, which sits between a client and the internet to mask the client's identity or enforce access policies.
| Feature | Forward proxy | Reverse proxy |
|---|---|---|
| Positioned in front of | Clients | Servers |
| Hides identity of | Client | Server |
| Common use case | Corporate firewalls, anonymity | Load balancing, SSL, caching |
Why use a reverse proxy?#
SSL / TLS termination#
The reverse proxy handles the TLS handshake, decrypts traffic, and forwards plain HTTP to internal services. This offloads CPU-intensive crypto from every backend and gives you a single place to manage certificates.
Client --HTTPS--> Reverse Proxy --HTTP--> Backend
Caching#
Static assets, API responses, and rendered pages can be cached at the proxy layer. A cache hit is served in microseconds without touching the backend at all.
Compression#
The proxy can gzip or brotli-compress responses before sending them to clients, reducing bandwidth without adding logic to each service.
Load balancing#
Distribute traffic across multiple backend instances using round-robin, least-connections, IP-hash, or weighted algorithms.
Security#
- Hide internal topology and IP addresses
- Rate-limit and throttle abusive clients
- Block malicious payloads with a web application firewall (WAF)
- Add security headers (HSTS, CSP, X-Frame-Options)
Common reverse proxy tools#
Nginx#
The most widely deployed reverse proxy and web server. Configuration is declarative and file-based.
upstream api_servers {
least_conn;
server 10.0.1.10:3000;
server 10.0.1.11:3000;
server 10.0.1.12:3000;
}
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/api.pem;
ssl_certificate_key /etc/ssl/private/api.key;
location / {
proxy_pass http://api_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_valid 200 10m;
}
}
HAProxy#
Purpose-built for high-performance TCP and HTTP load balancing. Excels at health checks and connection draining.
frontend http_front
bind *:443 ssl crt /etc/ssl/certs/combined.pem
default_backend api_back
backend api_back
balance roundrobin
option httpchk GET /healthz
server srv1 10.0.1.10:3000 check
server srv2 10.0.1.11:3000 check
Caddy#
Automatic HTTPS via Let's Encrypt with zero configuration. Great for smaller deployments and developer tooling.
api.example.com {
reverse_proxy 10.0.1.10:3000 10.0.1.11:3000 {
lb_policy least_conn
health_uri /healthz
}
encode gzip zstd
}
Traefik#
Designed for dynamic, container-native environments. Reads configuration from Docker labels, Kubernetes Ingress, or Consul.
# docker-compose labels
labels:
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.services.api.loadbalancer.server.port=3000"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
Envoy#
High-performance, programmable proxy used as the data plane in service meshes like Istio. Configured via xDS APIs for dynamic updates.
clusters:
- name: api_cluster
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api-service
port_value: 3000
Architecture patterns#
Single proxy, multiple backends#
Route by path or hostname to different services behind one proxy.
/api/* -> API service (port 3000)
/app/* -> Frontend service (port 8080)
/static/* -> Object storage / CDN origin
Proxy chain (edge + internal)#
An edge proxy (Cloudflare, AWS ALB) handles global traffic and DDoS protection. An internal proxy (Envoy sidecar) handles service-to-service routing and observability.
Sidecar proxy (service mesh)#
Each service gets its own Envoy sidecar. The control plane (Istio, Linkerd) manages routing rules, mTLS, retries, and circuit breaking centrally.
Security best practices#
- Terminate TLS at the proxy — use TLS 1.3, disable weak ciphers
- Set timeouts aggressively — read, write, and idle timeouts prevent slowloris attacks
- Restrict upstream headers — strip
X-Forwarded-Forspoofing from untrusted sources - Enable rate limiting — protect backends from traffic spikes
- Use health checks — remove unhealthy nodes automatically
- Log access and errors — structured JSON logs feed into your observability stack
Performance tuning#
- Connection pooling: reuse upstream connections to avoid repeated TCP handshakes
- Keepalive tuning: set
keepalive_timeoutandkeepalive_requeststo match your traffic patterns - Buffer sizes: tune
proxy_buffer_sizeto avoid spilling large headers to disk - Worker processes: match worker count to CPU cores, use
epoll(Linux) orkqueue(macOS)
Choosing the right tool#
| Tool | Best for | Auto HTTPS | Dynamic config | L4 support |
|---|---|---|---|---|
| Nginx | General-purpose web serving + proxy | No (manual) | Reload required | Yes |
| HAProxy | High-throughput TCP/HTTP balancing | No | Reload required | Yes |
| Caddy | Small teams wanting zero-config HTTPS | Yes | API + file | Yes |
| Traefik | Container-native, Kubernetes | Yes | Docker/K8s labels | Yes |
| Envoy | Service mesh, programmable data plane | No | xDS API | Yes |
Wrapping up#
A reverse proxy is foundational infrastructure. Whether you need SSL termination for a single app or a full service mesh across hundreds of microservices, the pattern is the same: place a proxy between clients and backends to gain security, observability, and operational flexibility.
This is article #240 on Codelit. If this guide helped clarify reverse proxy architecture, explore the rest of our library for deep dives on infrastructure, system design, and backend engineering.
Try it on Codelit
Chaos Mode
Simulate node failures and watch cascading impact across your architecture
Cost Estimator
See estimated AWS monthly costs for every component in your architecture
GitHub Integration
Paste a repo URL and generate architecture from your actual codebase
Related articles
Batch API Endpoints — Patterns for Bulk Operations, Partial Success, and Idempotency
8 min read
system designCircuit Breaker Implementation — State Machine, Failure Counting, Fallbacks, and Resilience4j
7 min read
testingAPI Contract Testing with Pact — Consumer-Driven Contracts for Microservices
8 min read
Try these templates
Netflix Video Streaming Architecture
Global video streaming platform with adaptive bitrate, CDN distribution, and recommendation engine.
10 componentsSearch Engine Architecture
Web-scale search with crawling, indexing, ranking, and sub-second query serving.
8 componentsGoogle Search Engine Architecture
Web-scale search with crawling, indexing, PageRank, query processing, ads, and knowledge graph.
10 componentsBuild this architecture
Generate an interactive Reverse Proxy Architecture in seconds.
Try it in Codelit →
Comments