Wheelhouse docs

Share load across two uplinks#

You will end up with new connections spread across two uplinks by weight, and a member dropped from the pool when its health tests fail. This is load-balancing wan, the third of VyOS' three ways to use more than one connection.

It balances connections, not packets. One download uses one uplink. Two uplinks of 100 Mbit/s do not make one 200 Mbit/s connection; they make two people's downloads independent.

Before you start#

Step 1 — Add a rule#

Network → High availability → Uplinks, the load-balancing panel.

A rule chooses which traffic is balanced and across what. Adding one from the page also adds the health test each member needs, because VyOS refuses a member without one.

set load-balancing wan rule 10 inbound-interface eth0
set load-balancing wan rule 10 interface eth1 weight 3
set load-balancing wan rule 10 interface eth2 weight 1
set load-balancing wan interface-health eth1 nexthop 203.0.113.1
set load-balancing wan interface-health eth1 test 10 target 9.9.9.9
set load-balancing wan interface-health eth2 nexthop 198.51.100.1
set load-balancing wan interface-health eth2 test 10 target 9.9.9.9
set load-balancing wan rule 10 failover
set load-balancing wan rule 10 description 'lan out'

The fields the panel offers:

FieldCommandFor
Inbound interfaceinbound-interface <if>Which traffic this rule governs; any matches everything
Members and weightsinterface <if> weight <n>The pool, and the share each takes
ExcludeexcludeKeep matching traffic on the main routing table instead of balancing it
FailoverfailoverMove flows off a failed member rather than dropping them
Per-packetper-packet-balancingBalance packets rather than connections. Almost always wrong; it reorders traffic.
Protocol, source, destination, portprotocol, source address, destination address, destination portNarrow the rule

exclude is the one people miss. Traffic that must not be balanced — a VPN whose far end pins your source address, a service that authenticates by IP — gets its own lower-numbered rule with exclude, so it keeps using the main table.

Step 2 — Decide about source NAT#

The balancer writes its own masquerade rules for its members unless you tell it not to:

set load-balancing wan disable-source-nat

Turn that on if you already have per-uplink NAT rules you want to keep. Two writers of masquerade rules is a configuration that works until it does not. Masquerade behind each uplink.

Step 3 — The other four switches#

All on the same panel, all one line each:

SwitchDoes
sticky-connections inboundReplies leave through the uplink the connection arrived on
enable-local-trafficBalance traffic the router itself originates. Off by default: only forwarded traffic is balanced.
flush-connectionsMove existing flows immediately when a member fails or returns, rather than letting them finish
only-default-routeBalance only traffic that would use the default route, leaving specific routes alone

Step 4 — Commit with a confirm window#

Check it worked#

The balancer's own report is where the health verdicts come from — active or failed, last change, failure count:

bash
show wan-load-balance

The Uplinks page joins that onto each uplink, and its stat tiles will now say load-balanced, or mixed if you also have protocols failover entries. Mixed is a real and reasonable state; the page names it rather than pretending you have one design.

Connections actually spread. From two clients, or two shells:

bash
curl -s https://ifconfig.co
curl -s https://ifconfig.co

Two different answers, in the ratio of the weights, over enough attempts. One answer every time means the rule is not matching — check its inbound interface — or a lower-numbered exclude rule is catching the traffic first.

Then fail a member and confirm traffic keeps flowing, the same way as in the failover guide.

Things that will bite#

Anything that authenticates by source address breaks. Banks, some VPN concentrators, some APIs. Give them an exclude rule.

TLS sessions that resume across uplinks can fail. sticky-connections inbound helps inbound; outbound stickiness is per-connection by design, so a client that opens a new connection may leave by the other uplink.

Removing a member's health test removes the member. VyOS refuses a member without one, so a commit that deletes a test and leaves the interface line fails.

Undoing it#

delete load-balancing wan rule 10
delete load-balancing wan interface-health eth2

The panel's row actions stage exactly those. Removing the whole load-balancing wan subtree returns to whatever ranking protocols static and the clients provide — check the Uplinks tab afterwards to see which uplink now wins.

See also#


Checked against docs/multi-wan.md · ui/src/pages/Wan.tsx · agent/wan.go

Updated 2026-09-02 multi-wan load-balancing uplink