Node: serve a probe endpoint with free bandwidth for client-side balancers

The Xray-core side of this idea is already proposed: Balancer: pick outbounds by real client-side throughput, not only by probe RTT · XTLS/Xray-core · Discussion #6752 · GitHub (client measures real throughput and can read a server hint).

Problem

Subscriptions with a balancer (leastPing / leastLoad + burstObservatory, as in the docs’ Xray JSON Advanced example) spread users badly: everybody picks the nearest node, even when its channel is small and already busy. In our setup one location had 21 online users vs 6 and 6 on others, while having the weakest uplink. The panel already knows each node’s traffic, but clients cannot see it. (Related: 💡 [REQUEST] - Add host randomization flag for subscription updates to optimize server load distribution · Issue #311 · remnawave/panel · GitHub)

Proposal

  1. Node setting: channel capacity, Mbit/s (entered by admin, e.g. 200 or 1000).
  2. Node serves a small probe endpoint reachable through its own inbounds (e.g. a routed domain → local responder inside rw-node):
    • /generate_204 — returns 204 with header X-Headroom-Mbps: <capacity − current usage> (absolute free bandwidth, not percent: a 200 Mbit/s node with 100 free is worse than a 1 Gbit/s node with 500 free);
    • /probe-1m — a 1 MB object for client throughput measurement.
    • Fail-safe: if the responder has no data, still answer 204 fast (never make the node look dead).
  3. In subscription templates: a helper to point burstObservatory destination to each node’s own probe.

Works today with plain RTT balancers (no harm), and becomes a real load signal once Xray reads the header.

See also Массовая смена активной ноды/хоста у пользователей — the answer there was that per-click switching is limited by the Xray core; this proposal plus the Xray one gives an automatic, core-level way to spread load.

1 Like