L4 vs L7 Load Balancing: Where the Balancer Looks

L4 vs L7 load balancing compared: the layer 4 load balancer's connection-level speed, the layer 7 load balancer's content aware routing, a decision table, and why real stacks chain both.

Executive Summary: L4 load balancers route by connection details like IP and port, while L7 balancers read the request itself, including paths, headers, and cookies. Here I cover TLS passthrough and the PROXY protocol at L4, request termination and cookie pinning at L7, content-aware routing for canaries and weighted splits, and why most stacks use both.

What is l4 vs l7 load balancing

An L4 load balancer routes connections. It sees the four-tuple (source and destination addresses and ports) and picks a backend, usually at the moment the TCP connection opens. From then on it forwards bytes: packets belong to the connection, the connection belongs to a backend, and the balancer never opens the envelope. TLS traffic is the tell: an L4 balancer passes encrypted bytes through untouched, unable to read a single request inside. Decryption would mean speaking layer 7.

An L7 load balancer routes requests. It terminates whatever it must (TCP, TLS, HTTP) and reads what arrives: method, path, headers, cookies, sometimes body. Each request can go to a different backend by different rules; each can be retried on another server when its server fails; each can be counted, limited, rewritten, or logged in full. The price is the work of parsing: every byte of every request crosses the balancer’s CPU. Every connection lives as long as the balancer holds it.

How this plays out in practice

As a result, the comparison the foundations article compressed into two bullets resolves, on inspection, into a question of ownership. At L4 the connection owns the routing decision: chosen once, kept until closed. At L7 the request owns it: chosen per ask, re-choosable on failure. Everything the two vantages do differently (health checking, pinning, retries, policy, cost) follows from that one difference, which the table below turns into dimensions.

Dimension L4 load balancer L7 load balancer
Architecture Routes connections on the four-tuple; forwards bytes; TLS passes through encrypted Terminates TCP and TLS; reads and routes each request; speaks the application protocol
Consistency Connection pinned to one backend for its lifetime; the decision is never revisited Per-request routing; retries and failover can move the work mid-conversation
Complexity Simple, fast, protocol-agnostic, but blind to content and per-request health More moving parts: parsing, TLS certificates, header rewriting, per-request state
Failure behavior Sees TCP health; a hung-but-open backend keeps receiving connections Per-request health: retries the ask on another backend; failures visible per request
Best fit Raw TCP/UDP traffic, TLS passthrough, very high connection rates, first hop in a chain HTTP/gRPC services, path-based routing, canaries, per-request policy, sticky sessions

Read the table as a spectrum of sight, not a ranking. The L4 column’s virtues (speed, simplicity, protocol blindness) are strongest exactly where the L7 column’s are impossible, and the reverse; that is why “which is better” answers itself with “better at what,” and why the chaining pattern at the end is not a hedge but the point.

Layer 4 load balancer

The layer 4 balancer’s decisions are per-connection. A new TCP handshake arrives; the balancer hashes or schedules the four-tuple, picks a backend. Either proxies the bytes (two connections stitched, client-to-balancer and balancer-to-backend) or, in direct server return, hands the backend the client’s address so replies can bypass the balancer entirely. DSR is the extreme version of the L4 philosophy: the balancer touches the conversation only at the door. At layer 4 there is nothing inside the door to see.

In contrast, TLS passthrough is the L4 signature move. Because the balancer never decrypts, certificates stay on the backends, encryption is genuinely end-to-end, and the balancer adds no certificate management to its life. The cost matches the virtue: it cannot read, rewrite, cache, or route on anything inside the encrypted stream, not the path, not the host header, not the cookie. Traffic that must stay encrypted to the last hop, and fleets that speak no HTTP at all, both point here.

Trade-offs worth weighing

The blind spot charges a price with a name: the PROXY protocol. When an L4 balancer forwards a connection, the backend sees the balancer’s IP as the client, so logging, rate limiting, and geolocation all misfire. PROXY protocol fixes it by prepending one line of plaintext: the real client’s address and port, before the proxied bytes, on the explicit convention that the backend knows to read it. It is a small protocol with a large lesson: at layer 4, preserving visibility is an opt-in convention, not a property.

What L4 cannot see, it cannot save. Health checks are TCP-level at best (a handshake proves the port is open, not that the application is sane) and a backend that accepts connections. Failing every request looks perfectly healthy from outside. Per-request retries are impossible when the request is invisible. A mid-connection failure ends the conversation and the client’s retry logic becomes the recovery plan. The layer 4 virtues are real; so is the blindness, and pricing both is the point of this comparison.

As a result, one more L4 virtue explains why the chaining pattern at the end exists: the front door’s job is connection arithmetic, and connection arithmetic is cheap. A first-hop balancer that merely spreads connections absorbs connection rates that would melt a fleet of parsers, then hands each connection to an L7 that pays parsing costs only for its share. The layer split is also a cost split: dumb and fast at the door, smart and slower inside.

Layer 7 load balancer

The layer 7 balancer’s first act is termination. It answers the TLS handshake with its own certificates, so certificates, their renewals. Their TLS configuration live on the balancer instead of on every backend, and it answers the TCP connection as the conversation’s other end. What was one encrypted client-to-backend conversation is now two: an encrypted one to the client. A plain or differently-encrypted one to the backend. Termination is the door through which everything else in this section walks.

Once it can read, routing becomes a decision per request. Paths can split fleets (/api/ to the service tier, static assets elsewhere) the idea the API gateway specializes and arms. Cookies can pin: the balancer sets or reads a cookie so request eleven returns to the server that remembers request ten; sticky sessions without caring which server holds the state. And failures become per-request: a backend that hangs mid-request can be retried on another, invisibly to the client. The balancer holds the request it can re-route.

Failure cases to expect

In contrast, the depth has protocol-level consequences worth naming. HTTP/2 changes the arithmetic: many requests multiplex over one connection. A balancer that routes per connection sends a whole conversation to one backend and loses the per-request freedom it was built for; serious L7 implementations parse the frames and route each stream, and gRPC rides the same rails and wants the same stream-awareness. The lesson runs in reverse of the websockets article’s: the deeper the protocol the balancer speaks, the more of its design it can honor.

The costs are the mirror of the L4 virtues. Every byte is parsed (CPU the L4 balancer never spent) and every connection is held as memory. TLS termination puts the balancer inside the encryption: an operator who can read its buffers can read the traffic, which is a trust decision as much as an engineering one. And an L7 balancer can be too helpful; rewriting headers or buffering bodies is occasionally exactly the bug. Sight is purchased; purchase carefully.

Per-request sight changes health checking too. An L4 check proves a port opens; an L7 check proves an endpoint answers; the balancer can send a real request to a health path and read the response. A fleet whose databases are down but whose web servers are up reports half-healthy instead of all-healthy. The health-check vocabulary grows from “is it listening” to “is it working,” which is the upgrade the load balancing fundamentals’ health-check section previews.

Content aware routing

As a result, content aware routing is what the sight is for. Path-based routing splits one public origin into many private fleets. Host headers send tenants to dedicated capacity. Header values choose environments; QA traffic carrying an internal header routes to the canary fleet while everyone else sails past. Weighted splits send one percent of users to a new version and the rest to the old: the mechanics behind canary deployment, operated from the balancer instead of the deploy pipeline.

The same sight drives per-request policy. Rate limits can be exact (per user, per endpoint, per minute) because the balancer reads the identifying headers; the rate limiting algorithms run best when the limiter can see what it is limiting. Rewrites can be surgical: one header added, one cookie stripped, one path normalized. And observability changes character: per-request logs and metrics see every request, not every connection; the difference between knowing a fleet is busy and knowing which endpoint is on fire.

Design details that matter

Session persistence is the feature that most often forces the layer choice. An L4 balancer pins by hashing the client’s IP: reliable until NAT puts an entire office behind one address, the failure mode the websockets article pinned. An L7 balancer pins by cookie, per user, not per address. Can even encrypt the routing hint into the cookie so any balancer in the fleet honors it statelessly. That one trick, encoding the decision in content instead of memory, is the content aware philosophy in miniature.

The honest closing of the payoff section: content awareness is not free, and more of it is not always better. Every rule evaluated is CPU per request; every cookie inspected is a privacy decision; every body read is a buffer held. The mature pattern is a short rule set doing the routing that matters (paths, splits, pins) and a fleet behind it that handles the rest. The balancer is a decision point, not an application server; the sight exists to route, and the routing should stop at what the rules need.

Common mistakes

  • Hashing on source IP behind NAT. Every user in one office shares one address, so the whole office shares one backend and one very bad afternoon. Cookie-based pinning at L7 (or consistent hashing on something stable) is the fix; the four-tuple is not a user identity.
  • Assuming passthrough and cookie pinning combine. They cannot, by construction: cookies live inside the encrypted body an L4 passthrough cannot read. End-to-end encryption and content-aware routing are different purchases; pick per fleet, and do not expect one vantage to honor the other’s promises.
  • Per-connection balancing an HTTP/2 conversation. Multiplexing means one connection carries many requests; a balancer that routes per connection pins them all to one backend. The balancer must speak the protocol deeply enough to route per stream, or the fleet’s per-request freedom quietly disappears.
  • Retrying at two layers at once. An L7 balancer that retries a failed request and a client that also retries builds a small request amplifier; attempts multiply under load, which is how a blip becomes a spike. Choose one retry owner; the retry with exponential backoff article prices the storm this mistake creates.
  • Treating the two vantages as rivals. The stack pattern is a chain: L4 spreads connections across L7 balancers, and each L7 parses and routes per request. The mistake is arguing L4 versus L7 as identity; they are two instruments, and the chain uses both because each covers the other’s blind spot.

FAQ

Which is faster, L4 or L7? L4, by construction: it forwards bytes and never parses, while L7 pays to terminate and read every request. But “faster” is the wrong axis; L4 is faster at moving traffic, L7 is faster at routing it well. Most stacks need both at different hops.

Can one load balancer do both L4 and L7? Most modern ones can: the same product exposes TCP/UDP listeners (L4) and HTTP listeners (L7), chosen per fleet. The layer is a property of how a listener treats its traffic, not a product category; the load balancing overview’s load-balancer-types row is this distinction in calmer clothes.

Where should TLS be terminated? Where the trust and the routing agree. Passthrough keeps encryption to the backend and suits traffic the balancer must not read; termination centralizes certificates and makes content routing possible, and is the default for public HTTP. The deciding facts are regulatory and architectural, not performance.

How does gRPC or HTTP/2 change L7 balancing? They raise the bar: many requests share one connection, so a balancer that routes per connection misroutes per-conversation. HTTP/2-aware and gRPC-aware balancing works per stream, restoring the per-request freedom, the same lesson websockets taught from the other direction.

Do sticky sessions belong at L4 or L7? If the pin key is an address, L4 hashing works until NAT breaks it; if the pin key is a user, L7 cookies are the honest tool, stable across networks and encodable statelessly. Pin by what identifies the session, not by what the balancer happens to see first.

  • Next read: load shedding, what happens when the balanced fleet is still drowning: overload survival, graceful degradation, and the deliberate choice of what to drop; the overflow question this cluster has been pointing at since the fundamentals.
  • load balancing in system design, the cluster’s foundation: the balancer’s job, the algorithms, the health checks, and the L4/L7 overview this article deepened.
  • reverse proxy, the other half of the box: TLS termination, routing, and the proxying functions that make most real-world “load balancers” L7 underneath.
  • API gateway, content aware routing specialized and armed: authentication, composition, and policy at the edge.
  • what are websockets, the connection type that stresses the layer choice: upgrades that must pass L4 hops, and pinning that needs L7 sight.

N-008 system-design

Share this article

2 thoughts on “L4 vs L7 Load Balancing: Where the Balancer Looks”

  1. Holly Sanders

    We run L4 in front and L7 only where we need path routing. Chaining both is underrated advice.

  2. Ramesh

    Content-aware routing at L7 costs latency we didn’t budget for. Wish we’d measured earlier.

Leave a Reply

Your email address will not be published. Required fields are marked *