Load balancer — distributing incoming traffic across multiple app instances
Beginner5 min read·eng-18-006
interviewperformance
Concept
Load balancer — a component that distributes incoming requests across multiple servers (backends). When you have 3 app servers, the load balancer decides which server handles each request.
Why load balancers exist:
- Horizontal scaling: Spread traffic across many servers.
- High availability: If one server dies, the load balancer routes traffic to the remaining healthy ones.
- Zero-downtime deployments: Deploy to servers one at a time, take them out of rotation, update, put back.
Load balancing algorithms:
- Round-robin: Requests go to server 1, then 2, then 3, then 1 again. Simple and even.
- Least connections: Routes to the server with the fewest active connections. Good when requests have variable processing time.
- IP hash: Same client IP always goes to the same server ("sticky sessions"). Useful for stateful apps.
- Weighted: Some servers get more traffic (e.g., larger servers get higher weight).
Layer 4 vs Layer 7:
- L4 (TCP): Routes at the network level. Doesn't inspect HTTP content. Very fast.
- L7 (HTTP): Routes based on HTTP — URL path, headers, host. Can route
/apito one server and/staticto another.
SSL termination: The load balancer handles HTTPS and forwards plain HTTP to backend servers. Backends don't need SSL certificates.
Health checks: Load balancers periodically ping backends (GET /health). If a server fails health checks, it's removed from rotation.
Tools: Nginx (common), HAProxy, AWS ALB/ELB, Caddy, Traefik (popular in Docker/K8s).
Code Example
nginx
# Nginx as a load balancer — nginx.conf
upstream app_servers {
# Round-robin by default
server app1:9000 weight=3; # gets 3x traffic (bigger server)
server app2:9000 weight=1;
server app3:9000 weight=1;
# Health check — remove server if it fails
# (nginx-plus feature; use least_conn with open-source)
least_conn; # route to server with fewest connections
}
server {
listen 80;
listen 443 ssl; # SSL termination here
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
location / {
proxy_pass http://app_servers; # distribute to upstream
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;
}
}php
<?php
// TRUSTING THE LOAD BALANCER in Laravel
// When requests come through a load balancer, the real client IP is in X-Forwarded-For
// app/Http/Middleware/TrustProxies.php
class TrustProxies extends Middleware
{
// Trust all proxies (or list specific IP ranges)
protected $proxies = '*';
protected $headers = Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_HOST
| Request::HEADER_X_FORWARDED_PORT
| Request::HEADER_X_FORWARDED_PROTO;
}
// After configuring TrustProxies:
$request->ip(); // returns actual client IP, not load balancer IP
$request->secure(); // returns true if original request was HTTPS, even if LB forwards as HTTP
// HEALTH CHECK ENDPOINT — load balancer pings this
Route::get('/health', function () {
// Check critical services
DB::select('SELECT 1');
Cache::put('health_check', true, 5);
return response()->json(['status' => 'ok']);
});
// If this returns non-200, load balancer removes this server from rotation