Skip to content
← Load Balancing · beginner · 8 min · 01 / 07

L4 vs L7 Load Balancing

The difference between routing packets and routing requests — when to use each layer and what each can see.

load balancingL4L7TCPHTTPnginxHAProxy

Real-World Analogy

A postal sorting facility vs a human receptionist: the sorter reads only the envelope (destination address, layer 4) and routes the package — fast, dumb, doesn’t open it. The receptionist reads the letter inside (content, layer 7) and can route based on what it says: “this goes to legal, this one to engineering.” More powerful, but more work per piece.

The OSI Model, Briefly

Load balancers operate at different layers of the network stack:

Layer 7 — Application  (HTTP, gRPC, WebSocket — reads headers, URLs, cookies)
Layer 4 — Transport    (TCP, UDP — reads IP:port only, never sees content)

The layer determines what the balancer can inspect and act on.

L4 Load Balancing

L4 balancers route based on IP address and port only. They never parse the HTTP payload — they forward raw TCP/UDP streams. The balancer doesn’t know about HTTP methods, paths, cookies, or hostnames.

Client → [L4 LB: TCP :443] → Backend server (raw stream forwarded)

Characteristics:

  • Extremely fast — minimal processing per connection
  • Works with any TCP/UDP protocol (databases, SMTP, custom binary protocols)
  • Backend sees the LB’s IP as the source (unless PROXY protocol is enabled)
  • Can’t route based on HTTP path or hostname
  • TLS is either passed through or terminated at the backend

Example — AWS NLB (Network Load Balancer) is L4:

  • Routes TCP connections to targets
  • Can’t inspect HTTP headers
  • Used for non-HTTP workloads or when you need maximum throughput

HAProxy L4 mode:

frontend tcp_in
    bind *:5432
    mode tcp
    default_backend postgres_backends

backend postgres_backends
    mode tcp
    balance roundrobin
    server db1 10.0.0.10:5432 check
    server db2 10.0.0.11:5432 check

This proxies PostgreSQL connections — HAProxy has no idea it’s a database; it’s just forwarding TCP.

L7 Load Balancing

L7 balancers terminate the connection and parse the full HTTP request. They can make routing decisions based on:

  • Host headerapi.example.com vs app.example.com
  • URL path/api/* vs /static/*
  • HTTP method — route POSTs differently from GETs
  • HeadersX-User-ID, Authorization, custom headers
  • Cookies — session affinity
  • Request body (rare, expensive)
Client → [L7 LB: TLS termination + HTTP parse] → Backend server (new connection)

Example — nginx L7 routing:

upstream api_servers {
    server 10.0.0.10:3000;
    server 10.0.0.11:3000;
}

upstream static_servers {
    server 10.0.0.20:80;
}

server {
    listen 443 ssl;
    server_name example.com;

    location /api/ {
        proxy_pass http://api_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static/ {
        proxy_pass http://static_servers;
    }

    location / {
        proxy_pass http://api_servers;
    }
}

HAProxy L7 mode:

frontend http_in
    bind *:80
    mode http
    acl is_api path_beg /api/
    use_backend api_servers if is_api
    default_backend web_servers

backend api_servers
    mode http
    balance leastconn
    server api1 10.0.0.10:3000 check
    server api2 10.0.0.11:3000 check

backend web_servers
    mode http
    balance roundrobin
    server web1 10.0.0.20:3000 check

Comparison

L4L7
InspectsIP + portFull HTTP request
TLSPass-through or backendTerminates at LB
Routing rulesIP/port onlyPath, host, headers, cookies
SpeedVery fastFast (small overhead)
ProtocolsAny TCP/UDPHTTP, gRPC, WebSocket
ObservabilityConnection countsRequest rates, status codes, latency

Choosing Between Them

Use L4 when:

  • The protocol isn’t HTTP (databases, SMTP, custom TCP)
  • You need maximum throughput with minimal overhead
  • You want to pass TLS all the way to the backend (end-to-end encryption without LB seeing plaintext)

Use L7 when:

  • You need path-based or host-based routing
  • You want TLS termination at the load balancer (simpler cert management)
  • You need to add/modify headers
  • You want per-request metrics (not just connection counts)
  • You’re building microservices where different paths go to different services

In practice: most web applications use L7. L4 appears at the edge (AWS NLB or hardware load balancers in data centers) passing traffic to L7 (nginx or HAProxy) closer to the application.

PROXY Protocol

L4 balancers mask the real client IP — the backend sees the balancer’s IP. PROXY protocol solves this by prepending connection metadata to the TCP stream:

PROXY TCP4 192.168.0.1 10.0.0.1 56324 443\r\n

Enable in HAProxy:

backend api_servers
    server api1 10.0.0.10:3000 send-proxy check

Configure the backend to parse it:

server {
    listen 3000 proxy_protocol;
    set_real_ip_from 10.0.0.0/8;
    real_ip_header proxy_protocol;
}

Now the backend sees the real client IP in X-Real-IP and access logs.