Skip to content

Performance

secnetperf-style micro-benchmarks over loopback UDP. Throughput figures use a real TLS 1.3 handshake (quic-go BenchmarkTransfer model); the installed-keys bypass is reserved for point latency micro-benchmarks only. Loopback throughput swings ±20% run-to-run — trends and orders of magnitude matter more than absolutes.

~390 MB/s
single-stream · real handshake
21.7 μs
echo latency · P50
~304 MB/s
4-stream aggregate
Caliber Single-stream Handshake What it tells you
Installed-keys, threaded std.Io ~1.94 GB/s bypassed raw transport ceiling (README headline); skips transport-parameter negotiation
Real TLS 1.3 handshake ~310–440 MB/s real the number real clients see; the headline on this page

The installed-keys path bypasses the handshake (and thus RFC 9000 §7.4 transport-parameter negotiation), so treat ~1.94 GB/s as a ceiling, not a client-facing figure.

Metric Value Notes
Single-stream throughput ~310–440 MB/s 3 runs: 313 / 318 / 440 (±20% run-to-run)
Handshake time ~0.6–1.0 ms/iter TLS 1.3, transport parameters negotiated (RFC 9000 §7.4)
Transfer 64 MB/iter 8900 B datagram, CUBIC, 100 μs receiveTimeout
Percentile Latency
P50 21.7 μs
P99 77.3 μs
P99.9 175.9 μs

5000 iterations, 1 KB full QUIC round-trip after a real handshake.

Multi-stream (4 concurrent) Value Notes
Aggregate ~304 MB/s stddev 4.5% — more stable than single-stream
Loss rate Throughput Notes
1% (loopback) 452 MB/s CUBIC fast recovery
5% (loopback) 303 MB/s
1% (100 μs RTT) 126 MB/s
5% (100 μs RTT) 120 MB/s

No UDP overhead — isolates the connection/CRYPTO state machine.

Metric Value Notes
Stream upload (16 MB) 0.35 GB/s CUBIC, cwnd = 272 KB
Echo P50 7.5 μs 1 KB full QUIC round-trip (in-memory)
Echo P99 47.7 μs tail varies with OS scheduling
Echo P99.9 665.2 μs
4-stream aggregate (4×4 MB) 0.34 GB/s shared cwnd
Metric Value
Real time 3.90 s
User CPU 3.21 s (~82% of one core)
Sys CPU 4.25 s (~109%, multi-core accumulated)
Peak RSS ~2.4 GB (bench arena accumulated, not production per-connection)

High sys CPU comes from per-packet UDP sendto/recvfrom syscalls; throughput is ACK-clock and shared-I/O-path limited, not pure CPU compute.

Cross-implementation throughput figures are quoted from external benchmarks (secnetperf, KIT 2025, TQUIC, quic-go#3670) — not measured by quicz. The full source-attributed table lives on the feature comparison page.

The nanoTime() helper has a Linux clock_gettime branch and all bench artifacts build on Linux, so the suite also runs in a native aarch64 Linux container. Loopback there goes through the Docker virtual NIC, so the numbers are environment-bound ceilings, not quicz limits:

Metric macOS (native) aarch64 Linux container
Single-stream (real handshake) ~426–507 MB/s ~51 MB/s (docker veth UDP ~60 MB/s ceiling)
DATAGRAM ~199 MB/s ~64 MB/s
Echo latency P50 20.1 μs 31.6 μs

Real bare-metal Linux throughput needs a non-virtualized host. Two runtime notes: drainOutgoing batches datagrams via sendMany (one sendmmsg syscall per batch on Linux; macOS keeps per-datagram sends), and receive buffers are pooled (a 16-entry pool instead of per-datagram allocation).

  • Protocol — QUIC v1; throughput runs do a real TLS 1.3 handshake per connection; installed 1-RTT keys only for latency micro-benchmarks.
  • Socket — loopback UDP, 8900-byte datagrams (macOS UDP limit 9000 B).
  • I/O layerstd.Io.Threaded (cross-platform; Linux auto-enables sendmmsg batching).
  • Buildzig build-exe -OReleaseFast.
  • Platform — Apple M-series, macOS, Zig 0.16.
  • Congestion — CUBIC (RFC 8312/9438); token-bucket pacer with ns precision.
  • Variance — ±20% run-to-run (system load, CUBIC window dynamics, thermal); ranges given where multiple runs were taken.
Terminal window
# Standardized suite: builds every benchmark (ReleaseFast), runs all in fixed
# order, records platform/commit metadata + full output under
# bench_results/<UTC timestamp>_<commit>.log (committed results are the baseline)
scripts/run_bench_suite.sh
zig build bench-suite # same order, no result recording
# Individual benchmarks
zig build run-quic-bench # installed-keys micro-benchmark
zig build run-quic-bench-hs # real-handshake throughput + latency
zig build run-quic-bench-simple # single-threaded raw processing
zig build run-quic-bench-datagram # RFC 9221 DATAGRAM throughput
zig build run-quic-bench-profile # per-phase profiling
zig build run-congestion-bench # NewReno vs CUBIC simulated loss
  • Real handshake, not bypass. Throughput uses a fresh TLS 1.3 handshake per iteration, so transport parameters are negotiated (RFC 9000 §7.4) — the installed-keys path skips that and is only for latency points.
  • ±20% variance. Loopback CUBIC at ~1 μs RTT makes single-stream runs noisy; multi-stream aggregate is steadier. Treat figures as orders of magnitude.
  • No GSO / XDP on macOS. The main per-packet cost is QUIC processing CPU (AES-128-GCM hw-accelerated ~4.9 μs/packet + framing); UDP sendto ~3.5–4.7 μs/packet is not dominant. Linux GSO/GRO (3–10×) or XDP would lift quicz.
  • Go / Rust benefit from zero-copy sendmsg + GSO on Linux, which this run does not exercise.
  • Echo latency (P50 / P99 / P99.9)
  • Multi-stream concurrency (4 streams)
  • Loss recovery (1% / 5%, loopback + 100 μs RTT)
  • CPU utilization
  • DATAGRAM throughput (RFC 9221)
  • External interop throughput (quic-go / quiche / s2n-quic peers)