August 28, 2026

Load Balancing: Why L4 and L7 Are Genuinely Different Tools

A load balancer distributes traffic across servers, but not all load balancers can see the same information about that traffic. Here's what actually separates a Layer 4 balancer from a Layer 7 one, and when each is the right choice.

backendnetworkinginfrastructurereliability

A load balancer sits in front of multiple backend servers and distributes incoming traffic across them, so no single server has to absorb all of it and so the system keeps working if one server fails. What varies significantly between load balancers is how much of the traffic they can actually see and act on, and that difference has a name: Layer 4 versus Layer 7, referring to layers of the OSI networking model.

Why the distinction matters

A Layer 4 load balancer operates on IP and TCP or UDP information: source and destination IP addresses and ports, without inspecting the actual content of the traffic. AWS's own documentation for its Network Load Balancer states this directly: it "functions at the fourth layer of the Open Systems Interconnection (OSI) model" and "can handle millions of requests per second." Because it never parses the traffic's payload, it's fast and cheap to run at very high volume, but it cannot make routing decisions based on anything inside an HTTP request. AWS documents that for TCP specifically, its Network Load Balancer routes using a flow hash computed from protocol, source and destination IP, and source and destination port, and that each individual TCP connection is routed to a single target for the life of that connection. It has no concept of what URL path or header a request is carrying.

A Layer 7 load balancer is HTTP-aware: it can parse and route based on URL path, host header, cookies, or other application-level information. This is what makes path-based routing possible (sending /api/* to one backend service and /static/* to another from the same load balancer), something a Layer 4 balancer fundamentally cannot do, because it never looks far enough into the traffic to see a URL at all. AWS's Application Load Balancer is the documented example of this tier, explicitly contrasted against its Network Load Balancer in AWS's own product materials.

The relevance is direct: Layer 4 is the right choice when raw throughput matters most and routing decisions don't need to depend on request content, such as balancing a fleet of identical backend instances. Layer 7 is necessary the moment routing needs to depend on what's inside the request, which describes most microservices architectures and any setup doing path- or header-based routing from a single entry point.

Algorithms

  • Round robin cycles through backend servers in order. It's nginx's default with no configuration required.
  • Weighted round robin biases that cycle toward specific servers, useful when backend capacity isn't uniform (nginx: server srv1.example.com weight=3;).
  • Least connections routes each new request to whichever backend currently has the fewest active connections (nginx's least_conn directive), which handles uneven request processing times better than round robin, since it accounts for actual current load rather than assuming every request costs the same.
  • IP hash, or consistent hashing, routes based on a hash of the client's IP, so the same client consistently reaches the same backend (nginx's ip_hash), giving session affinity without needing external session storage. Envoy's own engineering blog notes the broader industry trend toward consistent hashing as systems move from active-passive high-availability pairs to horizontally scalable fleets.

Named tools

nginx documents round robin, least connections, IP hash, and other algorithms, and includes passive health checking by default: marking a backend down after a configured number of consecutive failures (max_fails and fail_timeout) and periodically re-probing it with live traffic. Active health checking, sending synthetic probes independent of real traffic, is documented as an NGINX Plus (paid tier) feature specifically, worth knowing since it's a real distinction between the open-source and commercial versions. HAProxy supports the same core algorithm family and has a reputation for high-performance, high-scale deployments. Envoy is fundamentally a Layer 3/4 proxy with a pluggable filter chain, onto which an HTTP filter layer is added, meaning it explicitly supports both tiers within one architecture, and it documents active health checking combined with service discovery to determine which backends are eligible for traffic at any given moment.

Health checking itself is a core, universally documented load balancer responsibility, not an optional add-on: AWS's own documentation states that a load balancer "monitors the health of its registered targets, and routes traffic only to the healthy targets."

The resilience half: backpressure and circuit breakers

Load balancing distributes traffic; it doesn't, on its own, protect a system from being overwhelmed or from one failing dependency taking down everything that depends on it. Two related patterns address that.

Backpressure has a real, citable origin in the Reactive Streams specification, a cross-company initiative involving Netflix, Lightbend, and others, aimed at building "asynchronous streams of data with non-blocking back pressure." The mechanism: a slow consumer signals a fast producer to slow down or pause, rather than the producer simply overwhelming the consumer's buffer. This is directly analogous to what happens when a backend signals upstream, through 429 responses, connection refusal, or TCP-level flow control, that it cannot absorb more incoming traffic right now.

Circuit breakers originate from Michael Nygard's book Release It! Nygard's own framing: circuit breakers exist to allow one subsystem to fail without destroying the entire system, by wrapping calls to a risky integration point in a component that can stop making those calls when the system isn't healthy. Martin Fowler's widely cited restatement of the mechanics: a circuit breaker wraps a protected call, monitors for failures, and once failures cross a threshold, trips open, so further calls fail immediately without attempting the real call at all. This solves a specific, concrete problem: a hanging remote call that many callers pile up against can exhaust an entire pool of threads or connections, turning one slow dependency into a system-wide outage.

The pattern is implemented as a small state machine, most commonly with three states: closed (calls proceed normally, failures are tracked), open (calls fail immediately without being attempted, once a failure threshold is crossed), and half-open (after a cooldown period, a limited number of trial calls are allowed through to test whether the dependency has recovered before fully closing again). Netflix's Hystrix library popularized this exact state machine for microservices; its successor, resilience4j, implements the same three states with some refinements, including a configurable number of trial calls during half-open rather than Hystrix's single trial call.

Applying it

  • Choose Layer 4 when raw throughput is the priority and routing doesn't need to depend on request content. Choose Layer 7 the moment routing needs to see a URL path, header, or cookie.
  • Match the load-balancing algorithm to the actual traffic shape: round robin for uniform, cheap requests; least connections when request cost varies; consistent hashing when session affinity matters.
  • Treat health checking as mandatory, not optional, and know whether the tool in use does it actively, passively, or both, since that affects how quickly a genuinely failing backend gets removed from rotation.
  • Pair load balancing with backpressure and circuit breakers rather than treating traffic distribution alone as sufficient resilience. A load balancer spreads load across healthy backends; it doesn't stop a single unhealthy dependency from cascading into a wider outage on its own.