benchmarks
Measured on 2026-10-25 (Linux) and 2026-10-26 (macOS). Both cores were given the same config file and run as clients of servers on loopback, so these figures are the cost of the client itself rather than of a network.
Each figure is the lowest and highest of three rounds. The solid part of a bar reaches the lowest, the faint part the highest. The machines were loopback-only and some were shared with other builds, as noted under each chart, so a difference of a few percent is a tie. The raw tables and method are in BENCHMARKS.md.
proxy throughput, linux
Idle 4-vCPU Linux VM, four streams for 5 s. sing-box at HEAD (a6952cc), built with with_quic, with_utls, with_wireguard and with_gvisor; the servers are sing-box.
numbers
| path | sbr | sing-box |
|---|---|---|
| socks → direct | 36.2–37.3 | 34.8–39.8 |
| socks → shadowsocks-2022 | 19.4 | 16.7–17.7 |
| tun (system stack) → direct | 5.4–5.9 | 5.0–5.5 |
| vless + tls, up | 13.7–16.9 | 13.1–14.5 |
| vless + tls, down | 14.4–16.3 | 13.5–14.6 |
| trojan + tls, up | 15.5–17.5 | 13.0–14.4 |
| trojan + tls, down | 15.0–16.8 | 13.3–13.7 |
| vmess aes-128-gcm, up | 14.7–15.8 | 12.6–13.3 |
| vmess aes-128-gcm, down | 14.9–15.7 | 11.8–13.1 |
| hysteria2, up | 2.18–2.35 | 2.35–2.38 |
| wireguard, 4 streams, up | 1.97–2.33 | 2.46–2.77 |
| wireguard, 4 streams, down | 4.06–4.60 | 2.55–2.68 |
sbr is ahead on the encrypted paths. Plain TCP relay is level because sing-box uses splice(2) on Linux; Darwin has no splice, so on Apple platforms both cores copy. hysteria2 is level in throughput, with 8–15% less client CPU per GB for sbr. WireGuard upload is behind in this run, which predates the Darwin send-path change measured below.
vless + vision against xray, macos
Apple M1 Pro, Xray-core 26.10.21 with the reference deployment's configuration, Homebrew sing-box 1.14.4. Four streams for 5 s, three rounds back to back. The machine was in use during these runs, so compare the two clients within a row rather than with other charts.
numbers
| path | sbr | sing-box |
|---|---|---|
| plain inner, up | 9.02–9.19 | 7.68–7.89 |
| plain inner, down | 8.21–8.34 | 7.54–7.83 |
| tls inner, up | 11.75–11.98 | 11.66–11.86 |
| tls inner, down | 7.15–9.26 | 6.95–9.52 |
numbers
| path | sbr | sing-box |
|---|---|---|
| plain inner, up | 0.66–0.67 | 1.28–1.29 |
| plain inner, down | 1.10–1.18 | 1.39–1.45 |
| tls inner, up | 0.59–0.62 | 0.69–0.70 |
| tls inner, down | 1.04–1.58 | 1.09–1.78 |
On the padded path sbr is 5–20% faster and uses 15–49% less CPU per GB. With TLS inside the tunnel, where Vision copies directly, the two are level. The rows with TLS inside the tunnel vary widely between rounds for both clients.
The comparison uses Xray's TLS + Vision inbound because sing-box cannot connect to its REALITY inbound: sing-box removes X25519MLKEM768 from its REALITY ClientHello, which XTLS REALITY servers have refused since 2026-09-08. Over REALITY + Vision, sbr reached 8.9–9.3 Gbit/s up and 8.4–8.5 Gbit/s down in the same run.
hysteria2 against apernet hysteria, macos
Same machine and rounds, apernet hysteria 2.13.0 with Salamander.
numbers
| path | sbr | sing-box |
|---|---|---|
| up | 1.31–1.38 | 1.08–1.11 |
| down | 0.84–0.85 | 0.87–0.89 |
numbers
| path | sbr | sing-box |
|---|---|---|
| up | 7.40–7.68 | 13.52–13.75 |
| down | 13.31–13.47 | 21.05–21.52 |
Upload is 18–28% faster than sing-box at about 45% less CPU per GB; download is within 3–6% in throughput at 37% less CPU per GB. Two changes produced this. On Darwin, sbr sends and receives QUIC on a socket connected to the server, because macOS routes every unconnected sendto afresh and has no UDP GSO to amortise that cost; this halved upload CPU per GB. sbr also spreads streams over two QUIC connections, since one connection's packet processing runs on one core; on a phone this nearly doubled throughput.
wireguard, apple silicon
Apple M1 Pro, macOS, Homebrew sing-box 1.14.4 as the peer and as the comparison client, three rounds back to back. sbr runs on the single-thread runtime.
numbers
| path | sbr | sing-box |
|---|---|---|
| 1 stream, up | 1.90–1.94 | 1.65–1.67 |
| 1 stream, down | 0.61–0.62 | 0.60–0.61 |
| 4 streams, up | 1.65–1.71 | 1.41–1.57 |
| 4 streams, down | 0.56–0.58 | 0.60–0.64 |
numbers
| path | sbr | sing-box |
|---|---|---|
| 1 stream, up | 3.93–3.95 | 13.66–14.03 |
| 1 stream, down | 9.21–9.23 | 27.28–29.37 |
| 4 streams, up | 4.43–4.57 | 13.92–15.61 |
| 4 streams, down | 9.85–10.40 | 24.98–33.61 |
Upload is 5–21% faster than sing-box at 30% of its CPU per GB. Download is limited by the loopback sing-box server for both clients, and there sbr uses a third of sing-box's CPU per GB. Upload depends on connecting the UDP socket to its single peer: Darwin routes every unconnected sendto afresh, and connecting it more than doubled upload and halved its CPU per byte.
tun: kernel and userspace tcp stacks
OrbStack Linux VM with 8 vCPUs on an Apple M1 Pro, host shared with other builds (load average about 7); the two stacks ran back to back in each round. Four streams for 5 s from apps through the TUN, the engine and direct to a loopback server. CPU is whole-machine, including the kernel's own TCP work.
numbers
| path | userspace | kernel (system) |
|---|---|---|
| mtu 9000, up | 22.4–22.8 | 16.0–16.6 |
| mtu 9000, down | 19.1–19.5 | 15.2–15.7 |
| mtu 1280, up | 11.9–12.3 | 6.8–7.0 |
| mtu 1280, down | 9.8–10.2 | 6.6–6.7 |
numbers
| path | userspace | kernel (system) |
|---|---|---|
| mtu 9000, up | 0.47–0.48 | 0.65–0.68 |
| mtu 9000, down | 0.53–0.55 | 0.67–0.70 |
| mtu 1280, up | 0.75–0.78 | 1.35–1.40 |
| mtu 1280, down | 0.95–1.01 | 1.32–1.34 |
The kernel stack sends every segment through the kernel twice, from the app's socket to the TUN and from the TUN to sbr's listener; the userspace stack sends it once. The gap is widest at MTU 1280, where per-packet costs dominate. Both stacks are far faster than a phone's radio, so on a phone the CPU per byte is what matters. The app uses the userspace stack on iOS and tvOS. A real Darwin utun has not been measured yet.
reproduce
cargo build --release -p sbr-engine --examples throughput 4 5 <sing-box> proxy_bench <sing-box> 4 5 quic_throughput <sing-box> 4 5 wg_throughput <sing-box> 4 5 upstream_bench <xray> <hysteria> <sing-box> 4 5 3 tun_bench 4 5 # as root, Linux SBR_BENCH_MTU=1280 tun_bench 4 5