IPVS and ipvsadm:
balancing at layer 4, inside the kernel
Balancing connections without ever opening them: very fast, protocol-independent, and deliberately blind to content. Here is what it allows, what it rules out, and a case where it replaced a SQL proxy.
Table of contents
1. What “layer 4” actually means
IPVS balances connections, not requests. It looks at an address and a port, picks a target, and lets packets through without ever opening what they carry. It does not know whether this is HTTP, SQL or SMTP — and that is exactly where its strength comes from.
What it gives you
- • Performance that is hard to match: the work happens in the kernel, with no copy to user space
- • Weighting: a server twice as large takes twice as much
- • Protocol independence: anything over TCP or UDP can be balanced
- • A health check on the target, to pull it when it stops answering
What it rules out
- • Routing by URL: it lives in the payload, invisible at this level
- • Terminating encryption: that would mean decrypting, therefore opening
- • A genuinely application-level health check — an open port does not prove the application is well
- • Rewriting anything in the request
2. Three forwarding modes, and the one we pick
IPVS can forward traffic in three ways, and the choice has very concrete consequences on the network — far more than on the configuration.
| Mode | Return path | Constraint |
|---|---|---|
| NAT | Back through the balancer | Simplest to set up, but all return traffic transits the balancer, which becomes the bottleneck |
| Direct routing | Straight to the client | Targets must sit on the same segment and carry the virtual address on loopback without answering ARP for it |
| Tunnel | Straight to the client | Allows remote targets, at the cost of encapsulation and a reduced packet size |
Our default: direct routing
Because only the inbound path goes through the balancer. For a web service the return traffic is most of the volume: taking it off the path completely changes how the balancing machine has to be sized. In exchange, targets must be configured carefully — the virtual address on loopback, and above all ARP suppression, failing which several machines answer for the same address and the network becomes incoherent.
3. It is the same keepalived
The point that changes the decision, and that is often overlooked: you are not adding a tool. The daemon already carrying the floating address knows how to drive IPVS. You go from one role to two in the same configuration, with the same operations and the same on-call.
virtual_server 192.0.2.10 443 {
delay_loop 6 # interval between two checks
lb_algo wlc # least connections, weighted
lb_kind DR # direct routing
protocol TCP
real_server 10.0.0.11 443 {
weight 100 # this machine takes 2x more
TCP_CHECK { connect_timeout 3 }
}
real_server 10.0.0.12 443 {
weight 50
TCP_CHECK { connect_timeout 3 }
}
}
The same file holds the vrrp_instance block that keeps
the address alive. Both balancers watch each other, one carries the address, and whichever carries
it distributes. ipvsadm then serves mostly to
observe: it shows live connection counts per target, which is the fastest way to
check that weighting does what you think it does.
The limit of a layer-4 health check
A TCP_CHECK verifies that a port accepts
connections. It says nothing about the application behind it: a web server
returning a 500 on every request passes it effortlessly. When that distinction matters, you move
up to layer 7 —
or accept that application monitoring happens elsewhere.
4. From our own experience: a pure read stream
We have balanced a strictly read-only database stream with IPVS, with no SQL proxy at all. The usual reflex in front of a database is to reach for a proxy that understands the protocol. Here, none was needed.
Because the separation was already done
The application already opened two distinct connections: one to write, one to read. The read stream was therefore identified upstream, and all that remained was a distribution problem — which layer 4 solves perfectly, with a tool already in place and one extra piece.
It is the clearest illustration of the rule that runs through this subject: you only move up a level when you need what that level uniquely provides. A SQL proxy exists to decide statement by statement. If nobody needs that decision, it only brings one more component to operate, update and make redundant.
The caveat is the same as at level 5: balancing reads across replicas only makes sense if you know how current they are. IPVS does not watch replication lag — monitoring has to, and the application has to tolerate a slight delay. That subject lives on our MariaDB site.
5. Where layer 4 stops
IPVS is excellent as long as the balancing decision does not depend on content. Four needs force a move to layer 7 — and a fifth, often forgotten, mostly forces redundancy.
- • Routing by URL or header: impossible without reading the request.
- • Terminating encryption in one place, so certificates are not managed on every target.
- • Reliable sticky sessions: at layer 4 you only have the source address, a fragile criterion behind shared addressing.
- • A health check that actually tests the application, not just the port.
- • And in every case: the balancer has become the single path. Two machines and a floating address, otherwise you have moved the point of failure rather than removed it.
Frequently asked questions
IPVS or HAProxy: which should you choose?
The question is whether the balancing decision needs to consider request content. If not — a homogeneous TCP stream, interchangeable targets — IPVS does the job with better performance and fewer moving parts. As soon as you need routing by URL, TLS termination or a genuine application health check, HAProxy wins. The two can coexist: IPVS in front of several HAProxy instances is a classic design at very large scale.
Do the target servers need configuring for direct routing?
Yes, and that is the trade-off for the gain. Each target must carry the virtual address on its loopback interface and never answer ARP for it. If that suppression is not configured, several machines claim the same address on the network and behaviour becomes erratic — it is the classic mistake with this mode, and it shows up as intermittent symptoms that are hard to trace back.
Can you balance a database with IPVS?
Yes, on one condition: that the separation between reads and writes has already been made upstream by the application. We have deployed it on a strictly read-only stream and it works very well. If everything goes through the same connection, IPVS cannot tell anything apart and you need a proxy that speaks the database protocol.
Is ipvsadm for configuring or for observing?
Both, but in practice mostly observing. Durable configuration goes through keepalived, which also handles address failover and health checks. ipvsadm remains the most direct way to see, in real time, how many connections go to each target — and therefore to verify that weighting produces the effect you expect.
Does your balancer test the port, or the service?
It is the first thing we look at on an existing infrastructure. The answer decides whether you need layer 7 or simply better monitoring.
Get a quote