benchmarks · sbr

8 min read Original article ↗

Measured on 2026-10-26. Both cores were given the same config file and run as clients of servers on loopback, so most of these figures are the cost of the client itself rather than of a network; one section measures a real server over a home connection.

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

OrbStack Linux VM with 8 vCPUs on an Apple M1 Pro, four streams for 5 s, three rounds. sing-box 1.14.4 release build (linux-arm64); the servers are sing-box.

Throughput over TCP, sbr and sing-box as clients, Linux
Throughput over TCP, sbr and sing-box as clients, Linux, Gbit/s, higher is better sbr sing-box Gbit/s, higher is better 0 50 100 150 200 socks → direct 112.7–128.7 155.1–166.0 socks → shadowsocks-2022 44.8–49.5 31.6–45.1 vless + tls, up 38.6–45.2 38.2–42.5 vless + tls, down 41.5–48.0 39.4–42.3 trojan + tls, up 43.6–45.5 38.6–41.8 trojan + tls, down 42.4–48.4 38.8–41.7 vmess aes-128-gcm, up 39.8–43.0 36.8–38.6 vmess aes-128-gcm, down 39.3–40.1 35.4–36.9
numbers
pathsbrsing-box
socks → direct112.7–128.7155.1–166.0
socks → shadowsocks-202244.8–49.531.6–45.1
vless + tls, up38.6–45.238.2–42.5
vless + tls, down41.5–48.039.4–42.3
trojan + tls, up43.6–45.538.6–41.8
trojan + tls, down42.4–48.438.8–41.7
vmess aes-128-gcm, up39.8–43.036.8–38.6
vmess aes-128-gcm, down39.3–40.135.4–36.9
Throughput over UDP (QUIC and WireGuard), Linux
Throughput over UDP (QUIC and WireGuard), Linux, Gbit/s, higher is better sbr sing-box Gbit/s, higher is better 0 1 2 3 4 5 hysteria2, up 4.19–4.48 3.08–3.26 wireguard, 4 streams, up 3.02–3.07 2.05–2.14 wireguard, 4 streams, down 2.22–2.38 1.84–2.09
numbers
pathsbrsing-box
hysteria2, up4.19–4.483.08–3.26
wireguard, 4 streams, up3.02–3.072.05–2.14
wireguard, 4 streams, down2.22–2.381.84–2.09

sbr is ahead or level on every encrypted path: up to 18% on the TLS protocols, up to 57% on Shadowsocks-2022, 29–45% on hysteria2 upload at the same CPU per GB, and 41–50% on WireGuard upload at a fifth of the CPU per GB. Plain TCP relay to direct is the one row sing-box wins, by 20–47%: on Linux it moves bytes between two TCP sockets with splice(2) inside the kernel, while sbr copies them through userspace. Darwin has no splice, so on Apple platforms both copy.

through a real server

An M1 Pro on home Wi-Fi, each client a local SOCKS proxy to the same hysteria2 server (apernet hysteria, Hetzner, Salamander), downloading from a Hetzner speed-test file for 20 s, two rounds. With the tunnel off the same download ran at 472–500 Mbit/s.

hysteria2 download through a real server, macOS on Wi-Fi
hysteria2 download through a real server, macOS on Wi-Fi, Mbit/s, higher is better sbr sing-box Mbit/s, higher is better 0 200 400 600 download 566–574 515–553
numbers
pathsbrsing-box
download566–574515–553
Client CPU during that download
Client CPU during that download, % of one core, lower is better sbr sing-box % of one core, lower is better 0 20 40 60 80 100 download 51–60 87–92
numbers
pathsbrsing-box
download51–6087–92

sbr was 2–11% faster here at about 60% of sing-box's CPU. Both beat the direct download, because the server reaches the speed-test host by a better route than the home connection does. The server itself used roughly half a core while serving sbr at this rate.

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.

Throughput, VLESS + TLS + Vision against Xray-core, macOS
Throughput, VLESS + TLS + Vision against Xray-core, macOS, Gbit/s, higher is better sbr sing-box Gbit/s, higher is better 0 2.5 5 7.5 10 12.5 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
pathsbrsing-box
plain inner, up9.02–9.197.68–7.89
plain inner, down8.21–8.347.54–7.83
tls inner, up11.75–11.9811.66–11.86
tls inner, down7.15–9.266.95–9.52
Client CPU per GB, VLESS + TLS + Vision against Xray-core, macOS
Client CPU per GB, VLESS + TLS + Vision against Xray-core, macOS, CPU-s/GB, lower is better sbr sing-box CPU-s/GB, lower is better 0 0.5 1 1.5 2 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
numbers
pathsbrsing-box
plain inner, up0.66–0.671.28–1.29
plain inner, down1.10–1.181.39–1.45
tls inner, up0.59–0.620.69–0.70
tls inner, down1.04–1.581.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.

Throughput, hysteria2 (salamander) against apernet hysteria, macOS
Throughput, hysteria2 (salamander) against apernet hysteria, macOS, Gbit/s, higher is better sbr sing-box Gbit/s, higher is better 0 0.5 1 1.5 up 1.31–1.38 1.08–1.11 down 0.84–0.85 0.87–0.89
numbers
pathsbrsing-box
up1.31–1.381.08–1.11
down0.84–0.850.87–0.89
Client CPU per GB, hysteria2 (salamander) against apernet hysteria, macOS
Client CPU per GB, hysteria2 (salamander) against apernet hysteria, macOS, CPU-s/GB, lower is better sbr sing-box CPU-s/GB, lower is better 0 5 10 15 20 25 up 7.40–7.68 13.52–13.75 down 13.31–13.47 21.05–21.52
numbers
pathsbrsing-box
up7.40–7.6813.52–13.75
down13.31–13.4721.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.

Throughput, WireGuard, Apple silicon
Throughput, WireGuard, Apple silicon, Gbit/s, higher is better sbr sing-box Gbit/s, higher is better 0 0.5 1 1.5 2 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
pathsbrsing-box
1 stream, up1.90–1.941.65–1.67
1 stream, down0.61–0.620.60–0.61
4 streams, up1.65–1.711.41–1.57
4 streams, down0.56–0.580.60–0.64
Client CPU per GB, WireGuard, Apple silicon
Client CPU per GB, WireGuard, Apple silicon, CPU-s/GB, lower is better sbr sing-box CPU-s/GB, lower is better 0 10 20 30 40 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
numbers
pathsbrsing-box
1 stream, up3.93–3.9513.66–14.03
1 stream, down9.21–9.2327.28–29.37
4 streams, up4.43–4.5713.92–15.61
4 streams, down9.85–10.4024.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.

Throughput through the TUN, kernel and userspace TCP stacks, Linux
Throughput through the TUN, kernel and userspace TCP stacks, Linux, Gbit/s, higher is better userspace kernel (system) Gbit/s, higher is better 0 5 10 15 20 25 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
pathuserspacekernel (system)
mtu 9000, up22.4–22.816.0–16.6
mtu 9000, down19.1–19.515.2–15.7
mtu 1280, up11.9–12.36.8–7.0
mtu 1280, down9.8–10.26.6–6.7
Whole-machine CPU per GB through the TUN, kernel and userspace TCP stacks, Linux
Whole-machine CPU per GB through the TUN, kernel and userspace TCP stacks, Linux, CPU-s/GB, lower is better userspace kernel (system) CPU-s/GB, lower is better 0 0.5 1 1.5 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
numbers
pathuserspacekernel (system)
mtu 9000, up0.47–0.480.65–0.68
mtu 9000, down0.53–0.550.67–0.70
mtu 1280, up0.75–0.781.35–1.40
mtu 1280, down0.95–1.011.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