Hello, I'm not sure if this behavior is intended, I couldn't find any info about it nor anybody raising this issue.
Context:
I'm on Windows 11, using 3 interfaces (ethernet, wifi and wifi6). Download traffic gets perfectly balanced between them, but when testing uploading, it always use the ethernet connection. I've witnessed this with qBittorrent and specifically with online upload speed tests.
I've tried setting the ethernet as the less prioritary and the issue still appears. To my surprise, even leaving the ethernet interface out of the proxy the upload traffic always go through that connection. I've had to disable the ethernet interface in the OS to finally get the upload traffic going through one of the wifi interfaces, and it doesn't get balanced between them either. I've tested it with both Windows Internet Options and Proxifier.
After finding this, I've thought that maybe this is an OS restriction somehow, but I can't find any confirmation about it, and I guess it's worth to ask since the download traffic works fine.
These are my interfaces:
╔══════════╦═══════════════╗
║ Ethernet ║ 192.168.1.100 ║
╠══════════╬═══════════════╣
║ Wi-Fi ║ 192.168.1.133 ║
╠══════════╬═══════════════╣
║ Wi-Fi 2 ║ 192.168.1.134 ║
╚══════════╩═══════════════╝
This is my usual start config:
dispatch start 192.168.1.100/6 192.168.1.134/3 192.168.1.133/1
But I've tested with these as well and the issue is still there:
Ethernet as less prioritary dispatch start 192.168.1.100/1 192.168.1.134/6 192.168.1.133/3
Wifi only dispatch start 192.168.1.134 192.168.1.133
How to reproduce:
- Run dispatch
- Go to an upload-only online speed test, set the size to the max manually and start it.
- Watch the interfaces activity in the Task manager.
- Relaunch the test and watch again several times.
Expected result:
The upload traffic gets balanced between the interfaces at least once, according to the dispatch configuration.
Current result:
The upload traffic always go through the same interface (ethernet if available or the prioritary for the OS, ignoring the dispatch config).
Log with the 3 interfaces:
C:\dispatch>dispatch.exe --debug start 192.168.1.100/6 192.168.1.134/3 192.168.1.133/1
SOCKS proxy started on 127.0.0.1:1080
Dispatching to addresses 192.168.1.100/6,192.168.1.134/3,192.168.1.133/1
2025-12-29T10:08:26.202261Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:20930, socket: 600 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:20930 and 140.82.112.25:443
2025-12-29T10:08:29.889527Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:40040, socket: 684 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 1 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:40040 and 94.140.4.10:443
2025-12-29T10:08:33.610450Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:34270, socket: 708 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 3 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:34270 and 142.250.201.46:443
2025-12-29T10:08:33.619419Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:58464, socket: 692 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 2 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:58464 and 192.248.146.17:443
2025-12-29T10:08:35.296152Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:40040, socket: 684 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 1 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection terminated between 127.0.0.1:40040 and 94.140.4.10:443
2025-12-29T10:08:43.055231Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:11226, socket: 724 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.100, weight: 6 }, WeightedIp { ip: 192.168.1.134, weight: 3 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 4 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:11226 and 35.190.80.1:443
Log and screenshot leaving ethernet interface enabled but out of the dispatching:
C:\dispatch>dispatch.exe --debug start 192.168.1.134 192.168.1.133
SOCKS proxy started on 127.0.0.1:1080
Dispatching to addresses 192.168.1.134/1,192.168.1.133/1
2025-12-29T10:11:14.253411Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:63146, socket: 432 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:63146 and 140.82.114.26:443
2025-12-29T10:11:15.528139Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:32607, socket: 680 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 1, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:32607 and 192.248.146.17:443
2025-12-29T10:11:16.026577Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:24750, socket: 692 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:24750 and 94.140.4.11:443
2025-12-29T10:11:19.310060Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:6470, socket: 700 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 1, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:6470 and 104.26.5.115:443
2025-12-29T10:11:19.320427Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:59958, socket: 684 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:59958 and 104.26.5.115:443
2025-12-29T10:11:19.484112Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:62374, socket: 712 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 1, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:62374 and 35.190.80.1:443
2025-12-29T10:11:21.205216Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:24750, socket: 692 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection terminated between 127.0.0.1:24750 and 94.140.4.11:443
2025-12-29T10:11:24.234954Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:32607, socket: 680 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 1, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection terminated between 127.0.0.1:32607 and 192.248.146.17:443
2025-12-29T10:11:25.622624Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:20200, socket: 724 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:20200 and 192.248.146.17:443
2025-12-29T10:11:34.127868Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:20200, socket: 724 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection terminated between 127.0.0.1:20200 and 192.248.146.17:443
2025-12-29T10:11:41.340093Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:8000, socket: 732 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 1, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:8000 and 157.90.91.71:443
2025-12-29T10:11:41.516093Z INFO handle_socket{socket=PollEvented { io: Some(TcpStream { addr: 127.0.0.1:1080, peer: 127.0.0.1:45382, socket: 464 }) } dispatcher=WeightedRoundRobinDispatcher(Mutex { data: WeightedRoundRobinDispatcherInner { ipv4: State { ips: [WeightedIp { ip: 192.168.1.134, weight: 1 }, WeightedIp { ip: 192.168.1.133, weight: 1 }], ip_idx: 0, count: 0 }, ipv6: State { ips: [], ip_idx: 0, count: 0 } } })}: connection initiated between 127.0.0.1:45382 and 157.90.91.71:443
Screenshot (it is in Spanish, see the E: as the sending/outgoing traffic).
Ethernet is not included in the dispatch config:

Hello, I'm not sure if this behavior is intended, I couldn't find any info about it nor anybody raising this issue.
Context:
I'm on Windows 11, using 3 interfaces (ethernet, wifi and wifi6). Download traffic gets perfectly balanced between them, but when testing uploading, it always use the ethernet connection. I've witnessed this with qBittorrent and specifically with online upload speed tests.
I've tried setting the ethernet as the less prioritary and the issue still appears. To my surprise, even leaving the ethernet interface out of the proxy the upload traffic always go through that connection. I've had to disable the ethernet interface in the OS to finally get the upload traffic going through one of the wifi interfaces, and it doesn't get balanced between them either. I've tested it with both Windows Internet Options and Proxifier.
After finding this, I've thought that maybe this is an OS restriction somehow, but I can't find any confirmation about it, and I guess it's worth to ask since the download traffic works fine.
These are my interfaces:
This is my usual start config:
dispatch start 192.168.1.100/6 192.168.1.134/3 192.168.1.133/1But I've tested with these as well and the issue is still there:
Ethernet as less prioritary
dispatch start 192.168.1.100/1 192.168.1.134/6 192.168.1.133/3Wifi only
dispatch start 192.168.1.134 192.168.1.133How to reproduce:
Expected result:
The upload traffic gets balanced between the interfaces at least once, according to the dispatch configuration.
Current result:
The upload traffic always go through the same interface (ethernet if available or the prioritary for the OS, ignoring the dispatch config).
Log with the 3 interfaces:
Log and screenshot leaving ethernet interface enabled but out of the dispatching:
Screenshot (it is in Spanish, see the E: as the sending/outgoing traffic).
Ethernet is not included in the dispatch config: