Getting started

May 21, 2026 · View on GitHub

Setting up Rust

Make sure to have the latest stable version of Rust installed. We recommend using rustup for that.

After you did that, Rust should be fully installed.

Setting up Sōzu

Install

sozu is published on crates.io.

To install them, you only have to do cargo install sozu.

They will be built and available in the ~/.cargo/bin folder.

Build from source

Build the sozu executable and command line:

cd bin && cargo build --release --locked

The --release parameter informs cargo to compile sozu with optimizations turned on. Only use --release to make a production version.

The --locked flag tells cargo to stick to dependency versions as specified in Cargo.lock and thus prevent dependency breaks.

Run on NixOS

Sōzu is packaged in nixpkgs; the latest release is in the nixos-unstable channel.

Try it without installing:

nix-shell -p sozu --run "sozu --version"

Install it into your user profile:

nix profile install nixpkgs#sozu

Or add it to a NixOS system configuration:

environment.systemPackages = [ pkgs.sozu ];

The upstream derivation is currently marked broken on non-x86_64 platforms. Run Sōzu on an x86_64 NixOS host or build from source.

The derivation does not ship a services.sozu NixOS module. To run Sōzu as a daemon, write a systemd.services.sozu unit pointing at your config.toml; see the configuration reference.

Cargo features

The Cargo features published by the workspace tune behaviour and select the TLS crypto provider. Crypto-provider selection is documented in detail under Choosing a crypto provider below; the four providers (crypto-ring, crypto-aws-lc-rs, crypto-openssl, fips) are mutually exclusive at runtime via the precedence chain in lib/src/crypto.rs::default_provider().

FeatureCrate(s)Effect
tolerant-http1-parserlib, binRelaxes H1 parsing via kawa/tolerant-parsing.
simdlib, binEnables kawa/simd SIMD acceleration.
splicelib, binLinux-only zero-copy TCP forwarding via splice(2). Default 64 KiB kernel-pipe per session per direction; tunable via splice_pipe_capacity_bytes (clamped at /proc/sys/fs/pipe-max-size). Applies to Protocol::TCP listeners only.
opentelemetrylib, binCompiles in OpenTelemetry export.
logs-debugallCompiles in DEBUG logs (release strips them otherwise).
logs-traceallCompiles in TRACE logs (release strips them otherwise).
e2e-hookslibTest-injection APIs — never enable in production builds.

The authoritative list per crate lives in the per-crate Cargo.toml (lib/Cargo.toml, bin/Cargo.toml, command/Cargo.toml); cargo build --all-features --locked succeeds across the workspace today.

HTTP/2 support

Sōzu supports HTTP/2 out of the box, with no additional configuration needed for most use cases.

Frontend (client → Sōzu): HTTP/2 is automatically available on all HTTPS listeners. Clients negotiate the protocol during the TLS handshake via ALPN. To disable HTTP/2 on a specific listener, set alpn_protocols = ["http/1.1"].

Backend (Sōzu → server): By default, Sōzu speaks HTTP/1.1 to backends. To use cleartext HTTP/2 (h2c) for backend connections, set http2 = true on the cluster:

[clusters.MyCluster]
protocol = "http"
http2 = true
frontends = [
  { address = "0.0.0.0:8443", hostname = "app.example.com", certificate = "cert.pem", key = "key.pem", certificate_chain = "chain.pem" }
]
backends = [
  { address = "127.0.0.1:8080" }
]

Make sure buffer_size is at least 16393 (16384 max H2 frame + 9 byte header) in the global configuration section.

You can also toggle HTTP/2 at runtime using the CLI:

sozu cluster h2 enable --id MyCluster
sozu cluster h2 disable --id MyCluster

Security: Sōzu includes built-in flood detection for HTTP/2 connections, protecting against Rapid Reset (CVE-2023-44487), CONTINUATION flood (CVE-2024-27316), and other protocol abuse vectors. Thresholds are configurable per-listener — see the configuration reference for details.

Priorities: Sōzu implements RFC 9218 Extensible Priorities. Streams with the priority header (u=N, i format) are scheduled by urgency level, ensuring higher-priority responses are sent first.

See the configuration reference for all HTTP/2 options, or the H2 Mux Internals for developer-facing implementation details.

Choosing a crypto provider

Sōzu uses Rustls for TLS and supports multiple cryptographic backends, selected at compile time via feature flags. Only one crypto provider can be enabled at a time.

FeatureBackendNotes
crypto-ring (default)ringNo extra system dependencies
crypto-aws-lc-rsAWS-LCPost-quantum key exchange support. Requires cmake
crypto-opensslOpenSSL (via rustls-openssl)Uses the system OpenSSL. Requires cmake and OpenSSL dev headers
fipsAWS-LC in FIPS modeFIPS 140-3 compliance. Requires cmake
# Default build (ring)
cd bin && cargo build --release --locked

# AWS-LC with post-quantum support
cd bin && cargo build --release --locked --no-default-features --features crypto-aws-lc-rs

# OpenSSL backend
cd bin && cargo build --release --locked --no-default-features --features crypto-openssl

# FIPS 140-3 compliance (aws-lc-rs in FIPS mode)
cd bin && cargo build --release --locked --no-default-features --features fips

When using --no-default-features, the jemallocator allocator is also disabled. Add it back explicitly if desired: --features jemallocator,crypto-aws-lc-rs.

On FreeBSD and NetBSD the bundled jemalloc is never linked, even with the default feature set: the jemallocator Cargo dep is filtered out at the manifest level on those targets because libc already provides jemalloc as the system malloc(3) (FreeBSD 7.0+, NetBSD 5.0+). Sōzu defers to the system allocator there, and the --version banner reports -jemallocator to reflect the actual link graph.

Tune libc's jemalloc through the standard MALLOC_CONF environment variable. A few worked examples relevant to a reverse proxy:

# Hardening: zero freed regions, abort on OOM, fail-fast on bad config.
MALLOC_CONF="junk:true,abort_conf:true,confirm_conf:true,xmalloc:true"

# Background purging threads + arena count matched to worker count.
MALLOC_CONF="background_thread:true,narenas:4"

# Faster purging of dirty/muzzy pages on memory-tight hosts (defaults are
# 10 s = 10000 ms).
MALLOC_CONF="dirty_decay_ms:1000,muzzy_decay_ms:1000"

# Opt-in heap profiling, dump on SIGPROF or `mallctl prof.dump`.
# Requires libc jemalloc built with `--enable-prof` (FreeBSD/NetBSD
# default-on; check `man malloc.conf(5)` / `man jemalloc(3)`).
MALLOC_CONF="prof:true,prof_active:false,prof_prefix:/tmp/jeprof,lg_prof_sample:19"

# Print stats on exit (debugging only — high overhead).
MALLOC_CONF="stats_print:true"

NetBSD honours the same option names as FreeBSD; both follow the upstream jemalloc 5.x grammar (man malloc.conf(5) on FreeBSD, man jemalloc(3) on NetBSD).