Skip to content

Production tuning

Recommended configuration for deploying quicz in production. All parameters are set via ConnectionConfig (src/quic/connection_config.zig). Mirrors the repo’s production_tuning.md.

Parameter Default Recommended (production) Notes
pto_jitter_percentage 0 20–30 Prevents synchronized PTO timeouts across many concurrent connections. Range 0–50; enable for servers with 100+ connections.
congestion_algorithm .new_reno .cubic CUBIC (RFC 9438) with HyStart++ gives better throughput on high-BDP paths.
initial_rtt_ns 333 ms per environment Data center 1–5 ms; WAN 50–100 ms. Lower values speed initial window growth.
max_ack_delay_ns 25 ms 25 ms RFC 9000 default; do not change unless the peer negotiates differently.

PTO jitter adds ±percentage random variation to the base Probe Timeout before exponential backoff, decorrelating timeout storms when many connections share a path (behind a NAT or load balancer).

  • 0% (default) — deterministic PTO; fine for single connections and tests.
  • 20–30% (servers) — breaks synchronization without meaningfully delaying recovery.
  • 50% (max) — aggressive; may delay recovery on lossy paths.

The result is clamped to the RFC 9002 kGranularity floor (1 ms).

var conn = try Connection.init(allocator, .server, .{
.congestion_algorithm = .cubic,
.pto_jitter_percentage = 25,
.initial_rtt_ns = 5_000_000, // 5 ms for a data center
});

quicz’s CUBIC (RFC 9438) includes:

  • HyStart++ slow start — monitors RTT increases to exit slow start early (Conservative Slow Start, ÷4 growth, ≤5 rounds).
  • Fast retransmission — immediate retransmit on a congestion event, no PTO wait.
  • App-limited detection (RFC 8312 §5.8) — excludes app-limited periods from the CUBIC epoch; 3×MTU threshold avoids loopback false positives.
  • PTO jitter — optional randomized PTO (above).

The default. Simpler but less efficient on high-bandwidth, high-latency paths; fine for low-throughput control channels.

Removed in 2026-08 in favor of CUBIC (the repo guide predates the removal and still describes BBR as “available but not hardened”). Use CUBIC for production.

Environment Recommended initial_rtt_ns
Data center (same rack) 100_000–500_000 (0.1–0.5 ms)
Data center (cross-rack) 1_000_000–5_000_000 (1–5 ms)
Metro / CDN edge 10_000_000–30_000_000 (10–30 ms)
WAN / intercontinental 50_000_000–150_000_000 (50–150 ms)
Unknown / public internet 333_000_000 (333 ms, default)

The runtime.Server / runtime.Client (std.Io.Threaded) handle packet I/O, routing, and stream delivery automatically. A few deployment notes:

  • Send batching is automatic on LinuxdrainOutgoing collects drained datagrams into an OutgoingMessage[] and uses socket.sendMany (sendmmsg); macOS has no sendmmsg and keeps per-datagram sends. No configuration needed.
  • Receive buffers are pooled — the recv task uses a 16-entry buffer pool instead of allocating per datagram, falling back to the allocator when exhausted. Automatic.
  • SO_RCVBUF is raised to 4 MB on server and client sockets so bursts don’t overflow the kernel receive buffer before the drive task drains; loss recovery covers residual drops.
  • Idle timeoutmax_idle_timeout_ms (default 30 s in the runtime) closes connections that stop sending; tune to your keep-alive requirements.
  • Concurrency model — each Server runs one drive task that processes all accepted connections serially (single-threaded event loop, like s2n-quic / quiche / quic-zig). Per-connection multi-stream concurrency is already exploited. To scale aggregate multi-connection throughput across cores, run multiple Server instances on separate sockets/ports (SO_REUSEPORT is not plumbed through Zig std’s IpAddress.bind).
  • Bind addressServer.Config.bind_addr defaults to 127.0.0.1; set .{0,0,0,0} to accept remote clients.
  • Certificates on Linux x86_64 — use an RSA certificate (Zig 0.16 std.crypto has a P-256/P-384/Ed25519 signature-verification codegen bug on x86_64); aarch64 and macOS use ECDSA fine.