Load Balancing
debt(d7/e7/b7/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints note automated=no and tools listed (nginx, haproxy, aws-alb, cloudflare) are infrastructure components, not static analysis tools. Missing or misconfigured load balancing — such as no health checks, single point of failure, or stateful sessions without sticky sessions — only manifests under load or when a server fails. Code review might spot server-side session state, but the absence of a load balancer or its misconfiguration is largely invisible until production traffic or a failure event exposes it.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix mentions putting an Nginx or cloud load balancer in front of PHP-FPM workers, but common_mistakes reveal that stateful session handling (server-side $_SESSION) must also be addressed — requiring shared session storage or sticky sessions. This touches infrastructure configuration, application session management, health check endpoints, connection draining logic, and possibly deployment pipelines. It is not a single-line fix but a cross-cutting change spanning infrastructure and application layers.
Closest to 'strong gravitational pull' (b7). Load balancing applies_to web and api contexts broadly (PHP 5.0+). Once introduced, every future decision about session state, deployment strategy, health checks, and failover is shaped by the load balancer's presence and configuration. Stateless application design, shared caches, session storage backends, and zero-downtime deployments all orbit this architectural choice. It imposes a persistent tax on many work streams without being quite a full rewrite-or-live-with-it situation.
Closest to 'notable trap' (t5). The misconception is well-documented: round-robin distributes requests evenly, not load — expensive requests can overload one server while others sit idle. This is a documented gotcha that most developers eventually learn after observing uneven server utilization. It is a real operational surprise but not a catastrophic one, as least-connections or weighted algorithms are well-known remedies.
Also Known As
TL;DR
Explanation
Load balancers sit in front of PHP application servers and distribute traffic using algorithms: Round Robin (sequential rotation — simple, ignores server load), Least Connections (routes to the server with fewest active connections — better for variable request duration), IP Hash (sticky sessions by client IP — useful when server-side state isn't shared), and Weighted variants. For PHP applications, ensure session state is stored externally (Redis, database) rather than on-server — otherwise IP hash or sticky sessions are required, complicating scaling. Health checks detect failed upstream servers and remove them. Solutions: nginx upstream, HAProxy, AWS ALB, Cloudflare, and Traefik.
Diagram
flowchart TD
C1[Client] & C2[Client] & C3[Client] --> LB[Load Balancer]
LB -->|Round-robin| S1[Server 1]
LB -->|Round-robin| S2[Server 2]
LB -->|Round-robin| S3[Server 3]
S1 & S2 & S3 --> SESS[(Shared Session<br/>Redis)]
S1 & S2 & S3 --> DB[(Database)]
style LB fill:#d29922,color:#fff
style S1 fill:#238636,color:#fff
style S2 fill:#238636,color:#fff
style S3 fill:#238636,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Round-robin load balancing for stateful sessions without sticky sessions or shared session storage.
- No health checks on backend servers — unhealthy servers continue receiving traffic.
- Load balancer as a single point of failure — use active-passive or anycast for HA.
- Not draining connections before removing a backend — in-flight requests are dropped abruptly.
Avoid When
- Single-server setups — a load balancer in front of one server adds a network hop and a single point of failure.
- Sticky sessions on a stateless application — sticky sessions reduce effective distribution and complicate failover.
- Round-robin for backends with vastly different response times — use least-connections or weighted algorithms instead.
- Load balancing before the application is stateless — server-side sessions break when requests hit different nodes.
When To Use
- Horizontally scaled applications with multiple identical backend instances.
- High-availability requirements where a single backend failure must not cause downtime.
- Traffic distribution across instances in different availability zones for resilience.
- Zero-downtime deployments — route traffic away from instances being updated.
Code Examples
# nginx upstream with no health checks:
upstream app {
server app1:8080; # No health check — dead server gets traffic
server app2:8080;
}
# With health checks:
upstream app {
server app1:8080 max_fails=3 fail_timeout=30s;
server app2:8080 max_fails=3 fail_timeout=30s;
}
# nginx — upstream load balancing
upstream php_app {
least_conn; # send to server with fewest active connections
server app1.internal:9000;
server app2.internal:9000;
server app3.internal:9000 backup; # only used when others are down
keepalive 32; # reuse upstream connections
}
server {
location / {
proxy_pass http://php_app;
proxy_next_upstream error timeout http_503; # retry on failure
}
}
# Algorithms: round-robin (default), least_conn, ip_hash (sticky sessions),
# hash $request_uri (cache locality), random (nginx plus)