Topic Overview
Load Balancers (L4 vs L7)
Compare Layer 4 (transport) and Layer 7 (application) load balancers, their use cases, and when to use each type.
Load balancers distribute traffic across multiple servers. Layer 4 (L4) load balancers operate at the transport layer (TCP/UDP), while Layer 7 (L7) load balancers operate at the application layer (HTTP/HTTPS).
Layer 4 (L4) Load Balancer
Operates at: Transport Layer (TCP/UDP) Makes decisions based on: IP addresses and ports Does NOT inspect: Application data (HTTP headers, content)
How L4 Load Balancing Works
Client Request: TCP connection to 203.0.113.1:80
↓
L4 Load Balancer: Sees only IP and port
- Source IP: 192.168.1.100
- Source Port: 5000
- Dest IP: 203.0.113.1
- Dest Port: 80
↓
L4 Load Balancer: Routes based on algorithm
- Round robin, least connections, etc.
↓
Backend Server: Receives connection
- Server 1, 2, or 3
Characteristics:
- Fast: Minimal processing overhead
- Simple: Only looks at IP and port
- Transparent: Backend servers see original client IP
- Protocol agnostic: Works with any TCP/UDP protocol
Layer 7 (L7) Load Balancer
Operates at: Application Layer (HTTP/HTTPS) Makes decisions based on: HTTP headers, URLs, cookies, content Inspects: Full HTTP request
How L7 Load Balancing Works
Client Request: HTTP GET /api/users
↓
L7 Load Balancer: Inspects HTTP request
- URL: /api/users
- Host header: api.example.com
- Cookie: session_id=abc123
- Method: GET
↓
L7 Load Balancer: Routes based on content
- Route /api/users → user-service
- Route /api/orders → order-service
- Route based on session → sticky session
↓
Backend Server: Receives HTTP request
Characteristics:
- Intelligent routing: Can route based on URL, headers, content
- SSL termination: Can terminate SSL/TLS
- Content-based routing: Route different URLs to different services
- More overhead: Inspects application data
Comparison
| Feature | Layer 4 (L4) | Layer 7 (L7) |
|---|---|---|
| Layer | Transport (TCP/UDP) | Application (HTTP/HTTPS) |
| Decision based on | IP address, port | URL, headers, cookies, content |
| Performance | Very fast (low overhead) | Slower (more processing) |
| Protocol support | Any TCP/UDP | HTTP/HTTPS (primarily) |
| SSL termination | No | Yes |
| Content inspection | No | Yes |
| Sticky sessions | Limited (IP-based) | Full (cookie-based) |
| Health checks | TCP/UDP connection | HTTP status codes |
| Use case | High throughput, simple routing | Content-based routing, SSL termination |
Examples
L4 Load Balancer Configuration
# Nginx L4 Load Balancing (stream module)
stream {
upstream backend {
least_conn; # Algorithm
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
proxy_pass backend;
proxy_timeout 1s;
proxy_responses 1;
}
}
Characteristics:
- Routes based on IP and port only
- Fast, low latency
- Works with any TCP/UDP protocol
L7 Load Balancer Configuration
# Nginx L7 Load Balancing (http module)
http {
upstream user_service {
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream order_service {
ip_hash; # Sticky sessions
server 192.168.1.20:8080;
server 192.168.1.21:8080;
}
server {
listen 80;
# Route based on URL path
location /api/users {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/orders {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Characteristics:
- Routes based on URL path
- Can set custom headers
- Supports sticky sessions
L4 vs L7 Performance
# L4 Load Balancer (Simple, Fast)
class L4LoadBalancer:
def route(self, packet):
# Only look at IP and port
src_ip, src_port = packet.get_source()
dest_ip, dest_port = packet.get_destination()
# Simple routing algorithm
server = self.select_server(src_ip, src_port)
return server.forward(packet) # Fast, minimal processing
# L7 Load Balancer (Complex, Slower)
class L7LoadBalancer:
def route(self, request):
# Parse HTTP request
method = request.get_method()
url = request.get_url()
headers = request.get_headers()
cookies = request.get_cookies()
# Complex routing logic
if url.startswith('/api/users'):
server = self.user_service_pool.select()
elif url.startswith('/api/orders'):
server = self.order_service_pool.select()
elif 'session_id' in cookies:
server = self.get_server_for_session(cookies['session_id'])
else:
server = self.default_pool.select()
# Modify request (add headers, etc.)
request.set_header('X-Real-IP', request.get_client_ip())
return server.forward(request) # More processing overhead
Use Cases
Use L4 Load Balancer When:
- High throughput needed: Minimal processing overhead
- Protocol agnostic: Need to balance non-HTTP traffic (database, custom protocols)
- Simple routing: Route based on IP/port only
- Low latency critical: Fast forwarding without inspection
Examples:
- Database load balancing
- Custom TCP/UDP protocols
- High-performance web servers (simple routing)
Use L7 Load Balancer When:
- Content-based routing: Route based on URL, headers
- SSL termination: Terminate SSL at load balancer
- Sticky sessions: Route same user to same server
- Request/response modification: Add headers, modify content
- API gateway functionality: Rate limiting, authentication
Examples:
- Microservices routing (different URLs to different services)
- Web applications (session affinity)
- API gateways
- CDN edge servers
Common Pitfalls
- Using L7 for high throughput: L7 has more overhead. Fix: Use L4 for high throughput, L7 for content routing
- Not understanding layer differences: Confusing L4 and L7 capabilities. Fix: Understand L4 = IP/port, L7 = HTTP content
- SSL termination placement: Terminating SSL at L7 adds overhead. Fix: Consider SSL termination at L7 vs backend
- Sticky sessions at L4: L4 can only do IP-based stickiness. Fix: Use L7 for cookie-based sticky sessions
- Health check mismatch: L4 checks TCP connection, L7 checks HTTP. Fix: Use appropriate health checks
- Performance expectations: Expecting L7 to be as fast as L4. Fix: L7 will always have more overhead
Interview Questions
Beginner
Q: What is the difference between Layer 4 and Layer 7 load balancers?
A:
Layer 4 (L4) Load Balancer:
- Operates at: Transport layer (TCP/UDP)
- Makes decisions based on: IP addresses and ports
- Does NOT inspect: Application data (HTTP headers, content)
- Performance: Very fast (minimal processing)
- Use case: High throughput, simple routing
Layer 7 (L7) Load Balancer:
- Operates at: Application layer (HTTP/HTTPS)
- Makes decisions based on: URL, headers, cookies, content
- Inspects: Full HTTP request
- Performance: Slower (more processing overhead)
- Use case: Content-based routing, SSL termination
Example:
L4: Routes based on IP:port only
Client (192.168.1.100:5000) → Load Balancer → Server 1 or 2
L7: Routes based on HTTP content
GET /api/users → user-service
GET /api/orders → order-service
When to use:
- L4: High throughput, protocol agnostic, simple routing
- L7: Content-based routing, SSL termination, sticky sessions
Intermediate
Q: When would you choose L4 vs L7 load balancing? Explain with examples.
A:
Choose L4 When:
-
High Throughput Required
# Database load balancing # Need maximum performance, minimal overhead stream { upstream database { server db1:5432; server db2:5432; } } -
Non-HTTP Protocols
# Custom TCP protocol # L4 works with any TCP/UDP protocol stream { upstream custom_service { server service1:9000; server service2:9000; } } -
Simple Routing
# Just need to distribute load # No content-based routing needed upstream web_servers { server web1:80; server web2:80; }
Choose L7 When:
-
Content-Based Routing
# Route different URLs to different services location /api/users { proxy_pass http://user_service; } location /api/orders { proxy_pass http://order_service; } -
SSL Termination
# Terminate SSL at load balancer server { listen 443 ssl; ssl_certificate /path/to/cert.pem; proxy_pass http://backend; } -
Sticky Sessions
# Route same user to same server upstream backend { ip_hash; # Or cookie-based server server1:80; server server2:80; } -
Request Modification
# Add headers, modify requests proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Hybrid Approach:
- Use L4 for high-throughput services
- Use L7 for application-level routing
- Combine both in architecture
Senior
Q: Design a load balancing architecture for a high-traffic web application that handles 1 million requests per second. How do you combine L4 and L7 load balancers, handle SSL termination, and ensure high availability?
A:
class HighTrafficLoadBalancer {
private l4LoadBalancers: L4LoadBalancer[];
private l7LoadBalancers: L7LoadBalancer[];
private healthMonitor: HealthMonitor;
private sslTerminator: SSLTerminator;
constructor() {
// L4 load balancers for high throughput
this.l4LoadBalancers = [
new L4LoadBalancer({ algorithm: 'least_connections' }),
new L4LoadBalancer({ algorithm: 'least_connections' })
];
// L7 load balancers for content routing
this.l7LoadBalancers = [
new L7LoadBalancer({ sslTermination: true }),
new L7LoadBalancer({ sslTermination: true })
];
this.healthMonitor = new HealthMonitor();
this.sslTerminator = new SSLTerminator();
}
// Architecture: L4 → L7 → Backend
async handleRequest(request: Request): Promise<Response> {
// 1. L4 Load Balancer (First Layer)
// High throughput, minimal processing
const l4LB = this.selectL4LoadBalancer();
// Route to L7 load balancer pool
const l7LB = await l4LB.route(request, this.l7LoadBalancers);
// 2. L7 Load Balancer (Second Layer)
// Content-based routing, SSL termination
if (request.isHTTPS()) {
// SSL termination at L7
request = await this.sslTerminator.terminate(request);
}
// Content-based routing
const backend = await l7LB.route(request, {
'/api/users': this.userServicePool,
'/api/orders': this.orderServicePool,
'/api/payments': this.paymentServicePool
});
// 3. Backend Service
const response = await backend.handle(request);
// 4. Response Processing
return await l7LB.processResponse(response);
}
// L4 Load Balancer
class L4LoadBalancer {
async route(request: Request, targets: LoadBalancer[]): Promise<LoadBalancer> {
// Simple routing based on IP/port
// Fast, minimal overhead
const target = this.selectTarget(targets, request.getSourceIP());
return target;
}
}
// L7 Load Balancer
class L7LoadBalancer {
async route(request: Request, routes: Map<string, ServicePool>): Promise<Service> {
// Content-based routing
const url = request.getURL();
const path = this.extractPath(url);
// Route based on URL path
for (const [pattern, pool] of routes.entries()) {
if (path.startsWith(pattern)) {
return await pool.select(request);
}
}
// Default route
return await this.defaultPool.select(request);
}
async processResponse(response: Response): Promise<Response> {
// Add headers, modify response
response.setHeader('X-Load-Balancer', 'L7');
return response;
}
}
// SSL Termination
class SSLTerminator {
async terminate(request: HTTPSRequest): Promise<HTTPRequest> {
// Decrypt SSL at load balancer
// Reduces backend load
const decrypted = await this.decrypt(request);
return decrypted;
}
}
// Health Monitoring
class HealthMonitor {
async checkHealth(): Promise<HealthStatus> {
const checks = await Promise.all([
this.checkL4Health(),
this.checkL7Health(),
this.checkBackendHealth()
]);
return {
l4: checks[0],
l7: checks[1],
backend: checks[2]
};
}
}
}
Architecture:
Internet
↓
L4 Load Balancers (High Throughput)
↓
L7 Load Balancers (Content Routing, SSL Termination)
↓
Backend Services (Application Servers)
Features:
- Two-tier architecture: L4 for throughput, L7 for routing
- SSL termination: At L7 to reduce backend load
- Content-based routing: L7 routes to appropriate services
- High availability: Multiple L4 and L7 load balancers
- Health monitoring: Monitor all layers
- Scalability: Scale each layer independently
Key Takeaways
- L4 Load Balancer: Operates at transport layer (TCP/UDP), routes based on IP/port, fast, protocol agnostic
- L7 Load Balancer: Operates at application layer (HTTP/HTTPS), routes based on content, slower, more features
- Use L4 for: High throughput, non-HTTP protocols, simple routing
- Use L7 for: Content-based routing, SSL termination, sticky sessions, request modification
- Performance: L4 is faster (less overhead), L7 is slower (more processing)
- Hybrid approach: Use L4 → L7 → Backend for high-traffic applications
- Best practices: Use L4 for throughput, L7 for routing, terminate SSL at L7, monitor health