Bitruvius Imagery & 3D Suite / TurboZstd Track B - Drop-in Coming Soon

Same zstd wire. Memory-safe.

A memory-safe SIMD-optimized Zstandard encoder + decoder. RFC 8478 wire-format compatible - encoder output decodes via libzstd and ruzstd byte-for-byte. Every sample in our benchmark corpus round-trips cleanly through the reference libzstd - on both AVX2 and NEON, single- and multi-threaded.

Drop-in for libzstd (Facebook reference C zstandard, RFC 8478). SIMD backends: AVX2, NEON. ABI-level shim exports the ZSTD_* symbols GDAL, libtiff, rasterio, Zarr, Python zstandard, and Java zstd-jni import — replace the system libzstd binary, no recompile.

Headline

Faster encode from L5 up. Faster decode almost everywhere. Memory-safe drop-in.

Stated plainly, because honest benchmarks are the whole point: TurboZstd encodes faster than libzstd from level 5 upward — the lead grows through L5 and L9 and reaches several-fold at the archival L19–L22 levels — and decodes faster at every level except L1, where it sits at parity. The trade-offs we don't bury: at L1 and L3 the single-thread encoder is slower than libzstd's (those levels are already microseconds-fast, and at L1 we spend that time on a smaller file); and at the maximum-compression L19–L22 levels — plus optical at every level and AI-mask imagery above L1 — output runs a few percent larger, where libzstd's deeper match-finder still leads. We're smaller at L1 and L9, competitive in between. The win column differs by data type — find yours in the per-domain charts below.

L5-L9 single-thread encode
1.35-1.9× faster

than libzstd on AVX2 (L5 1.35×, L9 1.94×) at parity-to-smaller size — L9 lands 2.3% smaller. This is the crossover where we pull ahead on speed without giving up compression.

L19/L22 single-thread encode
5.6-11.2× faster

than libzstd on AVX2 (L19 5.64×, L22 11.23×). The trade-off, stated: archival output runs ~4% larger aggregate, where libzstd's deeper match-finder still leads.

L19/L22 multi-thread encode
7-74× per domain

than libzstd-ZSTDMT (par-vs-par) on NEON at L22 — libzstd's multi-thread barely parallelizes archival job sizes while encode_all_par splits cleanly (sar_vid 74×, most raster domains 16-40×).

Decode (AVX2, all levels)
0.97-1.28× libzstd

L1 just below parity (0.97×), then ahead from L3 up — 1.10× at L3 to 1.28× at L22. NEON decode trails today (0.77-0.99×); that's Mac's lane and closing.

Wire-format interop
Zero failures

Every row of the 9-domain corpus round-trips clean through the reference libzstd — AVX2 and NEON, single- and multi-thread. The output is real RFC 8478 zstd.

Throughput at-a-glance

Several-fold faster on archival. Decode wins from L3 up.

Single-thread encode and decode vs libzstd across the 804-sample corpus. The encoder is slower than libzstd at L1-L3 - those levels are already microseconds-fast - then pulls ahead at L5 and wins several-fold at the archival L19/L22 levels. The decoder sits at roughly parity at L1 on AVX2 (0.97×) and wins from L3 upward. The multi-thread (parallel) view is the next chart; the per-domain breakdown is further below.

Speed vs libzstd by compression level

Encode · AVX2 Encode · NEON Decode · AVX2 Decode · NEON — — 1× parity with libzstd
0.50×0.70×1.00×1.50×2.00×3.00×5.00×7.00×10.0×Speed multiplierL1L3L5L9L19L22Compression level0.51×0.77×1.35×1.94×5.64×11.2×

Log Y-axis so the full dynamic range fits - sub-1× on L1-L3 encode through several-fold at L22 encode. Dashed = NEON; solid = AVX2.

Multi-thread throughput at-a-glance

Parallel: we beat libzstd's own multi-thread from L3 up.

The deployed config for tiled raster: encode_all_par against libzstd's own ZSTDMT at the same worker count (8). TurboZstd's parallel encoder beats libzstd's multi-thread from L3 upward, and the lead compounds at archival sizes — AVX2 reaches 43× at L22, NEON 39× — because ZSTDMT barely parallelizes archival job sizes while encode_all_par splits cleanly. L1 trails in both (ZSTDMT barely-compresses fast there). NEON trails AVX2 in raw magnitude but wins the identical shape.

Parallel encode throughput vs libzstd ZSTDMT (8 workers)

Encode · AVX2 (par) Encode · NEON (par) — — 1× parity with libzstd
0.50×0.70×1.00×1.50×2.00×3.00×5.00×7.00×10.0×Speed × libzstd-ZSTDMTL1L3L5L9L19L22Compression level0.81×1.45×2.71×4.33×14.3×43.0×

encode_all_par vs libzstd ZSTDMT, 8 workers, par-vs-par. Our labeled corpus (16/domain; NEON L22 n=8), TurboZstd v0.0.4, 0 par-interop failures. Log Y-axis; dashed = NEON, solid = AVX2. Parallel is encode-only.

New in v0.0.4 · Negative levels

Throughput-first "fast" levels. Faster encode and decode, near-parity size.

TurboZstd now supports the full libzstd negative range (-1-131072) — the throughput-first tier that trades a little ratio for speed. On AVX2 it wins encode throughput at every negative level (1.19× → 1.47×) and decodes faster (1.17× → 1.31×), at near-parity size (+0.2% to +1.0% aggregate — byte-identical across both ISAs). On NEON, decode is the story — competitive-to-winning from -5 up (hyperspectral decode hits 2.0×); NEON negative-encode trails libzstd here (the compute-bound Apple-silicon finder — that encode win is AVX2-specific). Per-domain, hyperspectral/multispectral/RGB/quicklook/SAR-video lead; AI-inference and optical are the slower-at-shallow exceptions (optical also trades more ratio on the generic path). Output round-trips through the reference libzstd in both directions across the full range — zero interop failures.

Negative-level throughput vs libzstd (single-thread)

Encode · AVX2 Decode · AVX2 Decode · NEON — — 1× parity with libzstd
1.00×1.50×Speed multiplier-1-3-5-7-19Compression level1.19×1.24×1.41×1.47×1.47×

Single-thread, our labeled corpus (16 samples/domain, median), TurboZstd v0.0.4, 0 interop failures. Log Y-axis; dashed = NEON. NEON negative-encode trails (compute-bound) and is omitted to avoid implying a win it doesn't have — NEON is shown via its decode strength; see text.

Per-domain ROI

Your data type. Your win column.

Compression ratio and throughput against libzstd for each data type we benchmark. AVX2 (Intel Arrow Lake) and NEON (Apple M3) shown side-by-side; multi-thread shows TurboZstd's encode_all_par against libzstd's ZSTDMT with the same worker count. Above 1× = TurboZstd faster. Positive size = TurboZstd smaller.

AI Inference

Model inference output tensors (asphalt, vegetation, etc.)

233.9 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×10.0×20.0×AVX2 · single-threadL1: 0.57× encodeAVX2 · multi-threadL1: 1.05× encodeNEON · single-threadL1: 0.44× encodeNEON · multi-threadL1: 0.66× encodeL1AVX2 · single-threadL3: 0.59× encodeAVX2 · multi-threadL3: 1.33× encodeNEON · single-threadL3: 0.45× encodeNEON · multi-threadL3: 0.86× encodeL3AVX2 · single-threadL5: 1.25× encodeAVX2 · multi-threadL5: 2.39× encodeNEON · single-threadL5: 1.03× encodeNEON · multi-threadL5: 1.91× encodeL5AVX2 · single-threadL9: 1.10× encodeAVX2 · multi-threadL9: 1.95× encodeNEON · single-threadL9: 0.67× encodeNEON · multi-threadL9: 1.28× encodeL9AVX2 · single-threadL19: 4.10× encodeAVX2 · multi-threadL19: 6.83× encodeNEON · single-threadL19: 2.62× encodeNEON · multi-threadL19: 3.24× encodeL19AVX2 · single-threadL22: 22.4× encodeAVX2 · multi-threadL22: 20.3× encodeNEON · single-threadL22: 9.12× encodeNEON · multi-threadL22: 10.9× encodeL22DECODE — TurboZstd speedup × libzstd0.00×10.0×20.0×AVX2 · single-threadL1: 1.20× decodeNEON · single-threadL1: 0.70× decodeL1AVX2 · single-threadL3: 1.49× decodeNEON · single-threadL3: 0.88× decodeL3AVX2 · single-threadL5: 1.48× decodeNEON · single-threadL5: 0.92× decodeL5AVX2 · single-threadL9: 1.56× decodeNEON · single-threadL9: 0.81× decodeL9AVX2 · single-threadL19: 1.77× decodeNEON · single-threadL19: 1.03× decodeL19AVX2 · single-threadL22: 2.02× decodeNEON · single-threadL22: 0.99× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-10.0%0.0%+10.0%AVX2 · single-threadL1: +3.1% smallerAVX2 · multi-threadL1: +3.1% smallerNEON · single-threadL1: +3.1% smallerNEON · multi-threadL1: +3.1% smallerL1AVX2 · single-threadL3: -2.2% smallerAVX2 · multi-threadL3: -2.2% smallerNEON · single-threadL3: -2.2% smallerNEON · multi-threadL3: -2.2% smallerL3AVX2 · single-threadL5: -8.6% smallerAVX2 · multi-threadL5: -8.6% smallerNEON · single-threadL5: -8.6% smallerNEON · multi-threadL5: -8.6% smallerL5AVX2 · single-threadL9: -5.9% smallerAVX2 · multi-threadL9: -5.9% smallerNEON · single-threadL9: -5.9% smallerNEON · multi-threadL9: -5.9% smallerL9AVX2 · single-threadL19: -15.4% smallerAVX2 · multi-threadL19: -15.4% smallerNEON · single-threadL19: -15.4% smallerNEON · multi-threadL19: -15.4% smallerL19AVX2 · single-threadL22: -16.1% smallerAVX2 · multi-threadL22: -16.1% smallerNEON · single-threadL22: -16.1% smallerNEON · multi-threadL22: -16.1% smallerL22

Digital Surface Models

LiDAR-derived terrain elevation grids

587.5 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×20.0×40.0×AVX2 · single-threadL1: 0.57× encodeAVX2 · multi-threadL1: 1.03× encodeNEON · single-threadL1: 0.43× encodeNEON · multi-threadL1: 0.61× encodeL1AVX2 · single-threadL3: 0.63× encodeAVX2 · multi-threadL3: 1.64× encodeNEON · single-threadL3: 0.47× encodeNEON · multi-threadL3: 1.17× encodeL3AVX2 · single-threadL5: 1.09× encodeAVX2 · multi-threadL5: 2.93× encodeNEON · single-threadL5: 0.88× encodeNEON · multi-threadL5: 2.48× encodeL5AVX2 · single-threadL9: 1.15× encodeAVX2 · multi-threadL9: 4.47× encodeNEON · single-threadL9: 0.70× encodeNEON · multi-threadL9: 3.14× encodeL9AVX2 · single-threadL19: 7.33× encodeAVX2 · multi-threadL19: 24.6× encodeNEON · single-threadL19: 5.91× encodeNEON · multi-threadL19: 23.6× encodeL19AVX2 · single-threadL22: 14.3× encodeAVX2 · multi-threadL22: 42.4× encodeNEON · single-threadL22: 9.69× encodeNEON · multi-threadL22: 37.0× encodeL22DECODE — TurboZstd speedup × libzstd0.00×20.0×40.0×AVX2 · single-threadL1: 0.78× decodeNEON · single-threadL1: 0.67× decodeL1AVX2 · single-threadL3: 0.93× decodeNEON · single-threadL3: 0.80× decodeL3AVX2 · single-threadL5: 0.95× decodeNEON · single-threadL5: 0.83× decodeL5AVX2 · single-threadL9: 0.98× decodeNEON · single-threadL9: 0.84× decodeL9AVX2 · single-threadL19: 1.18× decodeNEON · single-threadL19: 1.10× decodeL19AVX2 · single-threadL22: 1.31× decodeNEON · single-threadL22: 1.09× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-10.0%0.0%+10.0%AVX2 · single-threadL1: +16.5% smallerAVX2 · multi-threadL1: +16.5% smallerNEON · single-threadL1: +16.5% smallerNEON · multi-threadL1: +16.5% smallerL1AVX2 · single-threadL3: -0.8% smallerAVX2 · multi-threadL3: -0.8% smallerNEON · single-threadL3: -0.8% smallerNEON · multi-threadL3: -0.8% smallerL3AVX2 · single-threadL5: -1.1% smallerAVX2 · multi-threadL5: -1.1% smallerNEON · single-threadL5: -1.1% smallerNEON · multi-threadL5: -1.1% smallerL5AVX2 · single-threadL9: -1.6% smallerAVX2 · multi-threadL9: -1.6% smallerNEON · single-threadL9: -1.6% smallerNEON · multi-threadL9: -1.6% smallerL9AVX2 · single-threadL19: -7.1% smallerAVX2 · multi-threadL19: -7.1% smallerNEON · single-threadL19: -7.1% smallerNEON · multi-threadL19: -7.1% smallerL19AVX2 · single-threadL22: -7.2% smallerAVX2 · multi-threadL22: -7.2% smallerNEON · single-threadL22: -7.2% smallerNEON · multi-threadL22: -7.2% smallerL22

Hyperspectral Imagery

100+ narrow spectral bands per pixel

913.9 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×10.0×20.0×30.0×AVX2 · single-threadL1: 0.37× encodeAVX2 · multi-threadL1: 0.72× encodeNEON · single-threadL1: 0.29× encodeNEON · multi-threadL1: 0.49× encodeL1AVX2 · single-threadL3: 0.67× encodeAVX2 · multi-threadL3: 1.73× encodeNEON · single-threadL3: 0.56× encodeNEON · multi-threadL3: 1.65× encodeL3AVX2 · single-threadL5: 1.17× encodeAVX2 · multi-threadL5: 2.94× encodeNEON · single-threadL5: 0.92× encodeNEON · multi-threadL5: 2.68× encodeL5AVX2 · single-threadL9: 2.15× encodeAVX2 · multi-threadL9: 4.30× encodeNEON · single-threadL9: 1.52× encodeNEON · multi-threadL9: 3.83× encodeL9AVX2 · single-threadL19: 5.64× encodeAVX2 · multi-threadL19: 22.1× encodeNEON · single-threadL19: 4.45× encodeNEON · multi-threadL19: 18.7× encodeL19AVX2 · single-threadL22: 7.82× encodeAVX2 · multi-threadL22: 30.8× encodeNEON · single-threadL22: 5.85× encodeNEON · multi-threadL22: 22.2× encodeL22DECODE — TurboZstd speedup × libzstd0.00×10.0×20.0×30.0×AVX2 · single-threadL1: 0.79× decodeNEON · single-threadL1: 0.55× decodeL1AVX2 · single-threadL3: 1.05× decodeNEON · single-threadL3: 0.99× decodeL3AVX2 · single-threadL5: 1.09× decodeNEON · single-threadL5: 1.07× decodeL5AVX2 · single-threadL9: 1.13× decodeNEON · single-threadL9: 1.07× decodeL9AVX2 · single-threadL19: 1.27× decodeNEON · single-threadL19: 1.17× decodeL19AVX2 · single-threadL22: 1.43× decodeNEON · single-threadL22: 1.14× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-5.0%0.0%+5.0%AVX2 · single-threadL1: +3.7% smallerAVX2 · multi-threadL1: +3.7% smallerNEON · single-threadL1: +3.7% smallerNEON · multi-threadL1: +3.7% smallerL1AVX2 · single-threadL3: +1.1% smallerAVX2 · multi-threadL3: +1.1% smallerNEON · single-threadL3: +1.1% smallerNEON · multi-threadL3: +1.1% smallerL3AVX2 · single-threadL5: -2.9% smallerAVX2 · multi-threadL5: -2.9% smallerNEON · single-threadL5: -2.9% smallerNEON · multi-threadL5: -2.9% smallerL5AVX2 · single-threadL9: -4.4% smallerAVX2 · multi-threadL9: -4.4% smallerNEON · single-threadL9: -4.4% smallerNEON · multi-threadL9: -4.4% smallerL9AVX2 · single-threadL19: -8.1% smallerAVX2 · multi-threadL19: -8.1% smallerNEON · single-threadL19: -8.1% smallerNEON · multi-threadL19: -8.1% smallerL19AVX2 · single-threadL22: -8.2% smallerAVX2 · multi-threadL22: -8.2% smallerNEON · single-threadL22: -8.2% smallerNEON · multi-threadL22: -8.2% smallerL22

Multispectral Imagery

Landsat / Sentinel-2 multi-band raster

565.8 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×20.0×40.0×AVX2 · single-threadL1: 0.39× encodeAVX2 · multi-threadL1: 0.74× encodeNEON · single-threadL1: 0.31× encodeNEON · multi-threadL1: 0.50× encodeL1AVX2 · single-threadL3: 0.66× encodeAVX2 · multi-threadL3: 1.62× encodeNEON · single-threadL3: 0.52× encodeNEON · multi-threadL3: 1.34× encodeL3AVX2 · single-threadL5: 1.18× encodeAVX2 · multi-threadL5: 2.71× encodeNEON · single-threadL5: 0.94× encodeNEON · multi-threadL5: 2.35× encodeL5AVX2 · single-threadL9: 1.99× encodeAVX2 · multi-threadL9: 4.06× encodeNEON · single-threadL9: 1.42× encodeNEON · multi-threadL9: 2.95× encodeL9AVX2 · single-threadL19: 6.94× encodeAVX2 · multi-threadL19: 26.0× encodeNEON · single-threadL19: 5.17× encodeNEON · multi-threadL19: 19.7× encodeL19AVX2 · single-threadL22: 13.8× encodeAVX2 · multi-threadL22: 42.0× encodeNEON · single-threadL22: 9.94× encodeNEON · multi-threadL22: 39.6× encodeL22DECODE — TurboZstd speedup × libzstd0.00×20.0×40.0×AVX2 · single-threadL1: 0.97× decodeNEON · single-threadL1: 0.64× decodeL1AVX2 · single-threadL3: 1.12× decodeNEON · single-threadL3: 0.91× decodeL3AVX2 · single-threadL5: 1.17× decodeNEON · single-threadL5: 1.02× decodeL5AVX2 · single-threadL9: 1.28× decodeNEON · single-threadL9: 1.08× decodeL9AVX2 · single-threadL19: 1.36× decodeNEON · single-threadL19: 1.14× decodeL19AVX2 · single-threadL22: 1.58× decodeNEON · single-threadL22: 1.08× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-5.0%0.0%+5.0%AVX2 · single-threadL1: +1.5% smallerAVX2 · multi-threadL1: +1.5% smallerNEON · single-threadL1: +1.5% smallerNEON · multi-threadL1: +1.5% smallerL1AVX2 · single-threadL3: +0.8% smallerAVX2 · multi-threadL3: +0.8% smallerNEON · single-threadL3: +0.8% smallerNEON · multi-threadL3: +0.8% smallerL3AVX2 · single-threadL5: -2.5% smallerAVX2 · multi-threadL5: -2.5% smallerNEON · single-threadL5: -2.5% smallerNEON · multi-threadL5: -2.5% smallerL5AVX2 · single-threadL9: -3.9% smallerAVX2 · multi-threadL9: -3.9% smallerNEON · single-threadL9: -3.9% smallerNEON · multi-threadL9: -3.9% smallerL9AVX2 · single-threadL19: -5.1% smallerAVX2 · multi-threadL19: -5.1% smallerNEON · single-threadL19: -5.1% smallerNEON · multi-threadL19: -5.1% smallerL19AVX2 · single-threadL22: -5.3% smallerAVX2 · multi-threadL22: -5.3% smallerNEON · single-threadL22: -5.3% smallerNEON · multi-threadL22: -5.3% smallerL22

Optical Imagery

RGB satellite + aerial photography (DOQQ, NAIP)

304.6 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×10.0×20.0×30.0×AVX2 · single-threadL1: 0.55× encodeAVX2 · multi-threadL1: 0.98× encodeNEON · single-threadL1: 0.46× encodeNEON · multi-threadL1: 0.67× encodeL1AVX2 · single-threadL3: 0.59× encodeAVX2 · multi-threadL3: 1.78× encodeNEON · single-threadL3: 0.53× encodeNEON · multi-threadL3: 1.55× encodeL3AVX2 · single-threadL5: 1.16× encodeAVX2 · multi-threadL5: 3.11× encodeNEON · single-threadL5: 1.00× encodeNEON · multi-threadL5: 3.03× encodeL5AVX2 · single-threadL9: 0.97× encodeAVX2 · multi-threadL9: 4.35× encodeNEON · single-threadL9: 0.69× encodeNEON · multi-threadL9: 2.97× encodeL9AVX2 · single-threadL19: 3.66× encodeAVX2 · multi-threadL19: 17.4× encodeNEON · single-threadL19: 2.59× encodeNEON · multi-threadL19: 14.2× encodeL19AVX2 · single-threadL22: 5.30× encodeAVX2 · multi-threadL22: 29.5× encodeNEON · single-threadL22: 3.29× encodeNEON · multi-threadL22: 17.6× encodeL22DECODE — TurboZstd speedup × libzstd0.00×10.0×20.0×30.0×AVX2 · single-threadL1: 0.79× decodeNEON · single-threadL1: 0.67× decodeL1AVX2 · single-threadL3: 1.12× decodeNEON · single-threadL3: 0.92× decodeL3AVX2 · single-threadL5: 1.13× decodeNEON · single-threadL5: 0.97× decodeL5AVX2 · single-threadL9: 1.14× decodeNEON · single-threadL9: 0.92× decodeL9AVX2 · single-threadL19: 1.35× decodeNEON · single-threadL19: 1.04× decodeL19AVX2 · single-threadL22: 1.51× decodeNEON · single-threadL22: 1.03× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-20.0%-10.0%0.0%+10.0%+20.0%AVX2 · single-threadL1: -4.4% smallerAVX2 · multi-threadL1: -4.4% smallerNEON · single-threadL1: -4.4% smallerNEON · multi-threadL1: -4.4% smallerL1AVX2 · single-threadL3: -3.3% smallerAVX2 · multi-threadL3: -3.3% smallerNEON · single-threadL3: -3.3% smallerNEON · multi-threadL3: -3.3% smallerL3AVX2 · single-threadL5: -13.9% smallerAVX2 · multi-threadL5: -13.9% smallerNEON · single-threadL5: -13.9% smallerNEON · multi-threadL5: -13.9% smallerL5AVX2 · single-threadL9: -9.5% smallerAVX2 · multi-threadL9: -9.5% smallerNEON · single-threadL9: -9.5% smallerNEON · multi-threadL9: -9.5% smallerL9AVX2 · single-threadL19: -17.2% smallerAVX2 · multi-threadL19: -17.2% smallerNEON · single-threadL19: -17.2% smallerNEON · multi-threadL19: -17.2% smallerL19AVX2 · single-threadL22: -18.1% smallerAVX2 · multi-threadL22: -18.1% smallerNEON · single-threadL22: -18.1% smallerNEON · multi-threadL22: -18.1% smallerL22

RGB Orthoimagery

High-resolution ortho-rectified RGB tiles

440.6 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×5.00×10.0×15.0×AVX2 · single-threadL1: 0.43× encodeAVX2 · multi-threadL1: 0.78× encodeNEON · single-threadL1: 0.28× encodeNEON · multi-threadL1: 0.49× encodeL1AVX2 · single-threadL3: 0.70× encodeAVX2 · multi-threadL3: 1.69× encodeNEON · single-threadL3: 0.45× encodeNEON · multi-threadL3: 1.43× encodeL3AVX2 · single-threadL5: 1.52× encodeAVX2 · multi-threadL5: 3.69× encodeNEON · single-threadL5: 1.09× encodeNEON · multi-threadL5: 3.54× encodeL5AVX2 · single-threadL9: 1.03× encodeAVX2 · multi-threadL9: 3.56× encodeNEON · single-threadL9: 0.57× encodeNEON · multi-threadL9: 2.67× encodeL9AVX2 · single-threadL19: 4.19× encodeAVX2 · multi-threadL19: 12.6× encodeNEON · single-threadL19: 3.49× encodeNEON · multi-threadL19: 12.9× encodeL19AVX2 · single-threadL22: 5.78× encodeAVX2 · multi-threadL22: 16.6× encodeNEON · single-threadL22: 4.58× encodeNEON · multi-threadL22: 16.3× encodeL22DECODE — TurboZstd speedup × libzstd0.00×5.00×10.0×15.0×AVX2 · single-threadL1: 1.16× decodeNEON · single-threadL1: 0.80× decodeL1AVX2 · single-threadL3: 1.35× decodeNEON · single-threadL3: 0.93× decodeL3AVX2 · single-threadL5: 1.41× decodeNEON · single-threadL5: 1.04× decodeL5AVX2 · single-threadL9: 1.24× decodeNEON · single-threadL9: 0.87× decodeL9AVX2 · single-threadL19: 1.59× decodeNEON · single-threadL19: 1.40× decodeL19AVX2 · single-threadL22: 1.62× decodeNEON · single-threadL22: 1.30× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-5.0%0.0%+5.0%AVX2 · single-threadL1: +1.1% smallerAVX2 · multi-threadL1: +1.1% smallerNEON · single-threadL1: +1.1% smallerNEON · multi-threadL1: +1.1% smallerL1AVX2 · single-threadL3: +0.1% smallerAVX2 · multi-threadL3: +0.1% smallerNEON · single-threadL3: +0.1% smallerNEON · multi-threadL3: +0.1% smallerL3AVX2 · single-threadL5: -1.8% smallerAVX2 · multi-threadL5: -1.8% smallerNEON · single-threadL5: -1.8% smallerNEON · multi-threadL5: -1.8% smallerL5AVX2 · single-threadL9: -0.1% smallerAVX2 · multi-threadL9: -0.1% smallerNEON · single-threadL9: -0.1% smallerNEON · multi-threadL9: -0.1% smallerL9AVX2 · single-threadL19: -6.4% smallerAVX2 · multi-threadL19: -6.4% smallerNEON · single-threadL19: -6.4% smallerNEON · multi-threadL19: -6.4% smallerL19AVX2 · single-threadL22: -6.4% smallerAVX2 · multi-threadL22: -6.4% smallerNEON · single-threadL22: -6.4% smallerNEON · multi-threadL22: -6.4% smallerL22

SAR CSI SLEDP

Synthetic-aperture radar complex single-look data

522.2 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×5.00×10.0×15.0×AVX2 · single-threadL1: 0.63× encodeAVX2 · multi-threadL1: 0.95× encodeNEON · single-threadL1: 0.44× encodeNEON · multi-threadL1: 0.66× encodeL1AVX2 · single-threadL3: 0.65× encodeAVX2 · multi-threadL3: 1.57× encodeNEON · single-threadL3: 0.46× encodeNEON · multi-threadL3: 1.15× encodeL3AVX2 · single-threadL5: 1.10× encodeAVX2 · multi-threadL5: 2.63× encodeNEON · single-threadL5: 0.83× encodeNEON · multi-threadL5: 2.45× encodeL5AVX2 · single-threadL9: 2.59× encodeAVX2 · multi-threadL9: 5.63× encodeNEON · single-threadL9: 1.59× encodeNEON · multi-threadL9: 4.26× encodeL9AVX2 · single-threadL19: 4.31× encodeAVX2 · multi-threadL19: 14.0× encodeNEON · single-threadL19: 3.53× encodeNEON · multi-threadL19: 16.0× encodeL19AVX2 · single-threadL22: 4.75× encodeAVX2 · multi-threadL22: 15.7× encodeNEON · single-threadL22: 4.19× encodeNEON · multi-threadL22: 18.5× encodeL22DECODE — TurboZstd speedup × libzstd0.00×5.00×10.0×15.0×AVX2 · single-threadL1: 1.07× decodeNEON · single-threadL1: 0.85× decodeL1AVX2 · single-threadL3: 1.12× decodeNEON · single-threadL3: 0.88× decodeL3AVX2 · single-threadL5: 1.12× decodeNEON · single-threadL5: 0.89× decodeL5AVX2 · single-threadL9: 1.17× decodeNEON · single-threadL9: 0.88× decodeL9AVX2 · single-threadL19: 1.20× decodeNEON · single-threadL19: 0.92× decodeL19AVX2 · single-threadL22: 1.32× decodeNEON · single-threadL22: 0.91× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-10.0%0.0%+10.0%AVX2 · single-threadL1: +11.5% smallerAVX2 · multi-threadL1: +11.5% smallerNEON · single-threadL1: +11.5% smallerNEON · multi-threadL1: +11.5% smallerL1AVX2 · single-threadL3: 0.0% smallerAVX2 · multi-threadL3: 0.0% smallerNEON · single-threadL3: 0.0% smallerNEON · multi-threadL3: 0.0% smallerL3AVX2 · single-threadL5: +0.1% smallerAVX2 · multi-threadL5: +0.1% smallerNEON · single-threadL5: +0.1% smallerNEON · multi-threadL5: +0.1% smallerL5AVX2 · single-threadL9: +0.4% smallerAVX2 · multi-threadL9: +0.4% smallerNEON · single-threadL9: +0.4% smallerNEON · multi-threadL9: +0.4% smallerL9AVX2 · single-threadL19: -0.7% smallerAVX2 · multi-threadL19: -0.7% smallerNEON · single-threadL19: -0.7% smallerNEON · multi-threadL19: -0.7% smallerL19AVX2 · single-threadL22: -1.2% smallerAVX2 · multi-threadL22: -1.2% smallerNEON · single-threadL22: -1.2% smallerNEON · multi-threadL22: -1.2% smallerL22

SAR CSI Quicklook

SAR amplitude quicklooks for browse imagery

87.0 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×5.00×10.0×AVX2 · single-threadL1: 0.31× encodeAVX2 · multi-threadL1: 0.65× encodeNEON · single-threadL1: 0.21× encodeNEON · multi-threadL1: 0.33× encodeL1AVX2 · single-threadL3: 0.61× encodeAVX2 · multi-threadL3: 1.25× encodeNEON · single-threadL3: 0.41× encodeNEON · multi-threadL3: 0.79× encodeL3AVX2 · single-threadL5: 1.14× encodeAVX2 · multi-threadL5: 2.15× encodeNEON · single-threadL5: 0.85× encodeNEON · multi-threadL5: 1.69× encodeL5AVX2 · single-threadL9: 1.04× encodeAVX2 · multi-threadL9: 1.88× encodeNEON · single-threadL9: 0.60× encodeNEON · multi-threadL9: 1.16× encodeL9AVX2 · single-threadL19: 2.43× encodeAVX2 · multi-threadL19: 4.40× encodeNEON · single-threadL19: 2.03× encodeNEON · multi-threadL19: 3.61× encodeL19AVX2 · single-threadL22: 5.83× encodeAVX2 · multi-threadL22: 11.0× encodeNEON · single-threadL22: 3.54× encodeNEON · multi-threadL22: 6.53× encodeL22DECODE — TurboZstd speedup × libzstd0.00×5.00×10.0×AVX2 · single-threadL1: 0.78× decodeNEON · single-threadL1: 0.52× decodeL1AVX2 · single-threadL3: 1.23× decodeNEON · single-threadL3: 0.84× decodeL3AVX2 · single-threadL5: 1.35× decodeNEON · single-threadL5: 0.98× decodeL5AVX2 · single-threadL9: 1.15× decodeNEON · single-threadL9: 0.84× decodeL9AVX2 · single-threadL19: 1.15× decodeNEON · single-threadL19: 1.07× decodeL19AVX2 · single-threadL22: 1.34× decodeNEON · single-threadL22: 1.06× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-5.0%0.0%+5.0%AVX2 · single-threadL1: -2.2% smallerAVX2 · multi-threadL1: -2.2% smallerNEON · single-threadL1: -2.2% smallerNEON · multi-threadL1: -2.2% smallerL1AVX2 · single-threadL3: -3.0% smallerAVX2 · multi-threadL3: -3.0% smallerNEON · single-threadL3: -3.0% smallerNEON · multi-threadL3: -3.0% smallerL3AVX2 · single-threadL5: -4.8% smallerAVX2 · multi-threadL5: -4.8% smallerNEON · single-threadL5: -4.8% smallerNEON · multi-threadL5: -4.8% smallerL5AVX2 · single-threadL9: -3.8% smallerAVX2 · multi-threadL9: -3.8% smallerNEON · single-threadL9: -3.8% smallerNEON · multi-threadL9: -3.8% smallerL9AVX2 · single-threadL19: -2.3% smallerAVX2 · multi-threadL19: -2.3% smallerNEON · single-threadL19: -2.3% smallerNEON · multi-threadL19: -2.3% smallerL19AVX2 · single-threadL22: -2.3% smallerAVX2 · multi-threadL22: -2.3% smallerNEON · single-threadL22: -2.3% smallerNEON · multi-threadL22: -2.3% smallerL22

SAR VID SLEDP

Video synthetic-aperture radar frames

4624.0 MiB corpus

AVX2 · single-thread AVX2 · multi-thread NEON · single-thread NEON · multi-thread — — 1× / 0% parity with libzstd
ENCODE — TurboZstd speedup × libzstd0.00×20.0×40.0×60.0×AVX2 · single-threadL1: 0.56× encodeAVX2 · multi-threadL1: 0.76× encodeNEON · single-threadL1: 0.39× encodeNEON · multi-threadL1: 0.45× encodeL1AVX2 · single-threadL3: 0.89× encodeAVX2 · multi-threadL3: 1.16× encodeNEON · single-threadL3: 0.62× encodeNEON · multi-threadL3: 0.96× encodeL3AVX2 · single-threadL5: 1.53× encodeAVX2 · multi-threadL5: 2.48× encodeNEON · single-threadL5: 1.10× encodeNEON · multi-threadL5: 1.95× encodeL5AVX2 · single-threadL9: 2.65× encodeAVX2 · multi-threadL9: 5.13× encodeNEON · single-threadL9: 1.61× encodeNEON · multi-threadL9: 3.42× encodeL9AVX2 · single-threadL19: 6.37× encodeAVX2 · multi-threadL19: 11.1× encodeNEON · single-threadL19: 4.20× encodeNEON · multi-threadL19: 11.4× encodeL19AVX2 · single-threadL22: 14.4× encodeAVX2 · multi-threadL22: 63.2× encodeNEON · single-threadL22: 11.9× encodeNEON · multi-threadL22: 74.0× encodeL22DECODE — TurboZstd speedup × libzstd0.00×20.0×40.0×60.0×AVX2 · single-threadL1: 1.04× decodeNEON · single-threadL1: 0.85× decodeL1AVX2 · single-threadL3: 1.11× decodeNEON · single-threadL3: 1.00× decodeL3AVX2 · single-threadL5: 1.12× decodeNEON · single-threadL5: 1.00× decodeL5AVX2 · single-threadL9: 1.10× decodeNEON · single-threadL9: 0.93× decodeL9AVX2 · single-threadL19: 1.00× decodeNEON · single-threadL19: 0.85× decodeL19AVX2 · single-threadL22: 1.15× decodeNEON · single-threadL22: 0.88× decodeL22SIZE — TurboZstd vs libzstd (positive = smaller, win)-5.0%0.0%+5.0%AVX2 · single-threadL1: +5.3% smallerAVX2 · multi-threadL1: +5.3% smallerNEON · single-threadL1: +5.3% smallerNEON · multi-threadL1: +5.3% smallerL1AVX2 · single-threadL3: -1.4% smallerAVX2 · multi-threadL3: -1.4% smallerNEON · single-threadL3: -1.4% smallerNEON · multi-threadL3: -1.4% smallerL3AVX2 · single-threadL5: +0.3% smallerAVX2 · multi-threadL5: +0.3% smallerNEON · single-threadL5: +0.3% smallerNEON · multi-threadL5: +0.3% smallerL5AVX2 · single-threadL9: +4.9% smallerAVX2 · multi-threadL9: +4.9% smallerNEON · single-threadL9: +4.9% smallerNEON · multi-threadL9: +4.9% smallerL9AVX2 · single-threadL19: -2.6% smallerAVX2 · multi-threadL19: -2.6% smallerNEON · single-threadL19: -2.6% smallerNEON · multi-threadL19: -2.6% smallerL19AVX2 · single-threadL22: -2.8% smallerAVX2 · multi-threadL22: -2.8% smallerNEON · single-threadL22: -2.8% smallerNEON · multi-threadL22: -2.8% smallerL22

Measured on the full Bitruvius corpus - 804 samples across nine diverse imagery types - single- and multi-threaded, on Intel (AVX2) and Apple Silicon (NEON). The multi-threaded figures run both TurboZstd and libzstd at 8 threads.

Why switch

A library swap. Not a migration.

  • - Size where it's read most: ~5% smaller at L1, ~2.3% smaller at L9 aggregate, with parity through L3-L5; several domains post double-digit L1 wins (dsm 16.5%, sar_csi 11.5%). The honest trade: archival L19-L22 and optical/AI-mask imagery run a few percent larger.
  • - Archival single-thread: 5.6× / 11.2× faster than libzstd on L19 / L22 (AVX2). Per-domain peaks: dsm L19 7.33×, ai_inference L22 22.4×, sar_vid L22 14.4×.
  • - Archival multi-thread: encode_all_par extends the lead far past single-thread — per-domain L22 runs 7-74× over libzstd-ZSTDMT on NEON (sar_vid 74×, most raster domains 16-40×).
  • - L9 multi-thread runs ~3.1× over libzstd-ZSTDMT (NEON, par-vs-par) at ~2% smaller output; encode_all_par beats libzstd's own ZSTDMT from L3 up (1.21× → 38×), while L1 still trails in both modes.
  • - Memory-safe: no C build dependency on developer workstations, CI runners, or customer build farms.
  • - Permissive licensing chain: TurboZstd is independent (RFC 8478 only, no libzstd code) — binary attribution graph is just LICENSE + NOTICE.
  • - Deterministic output: same input + same level always yields the same bytes, and the parallel encoder is worker-count-invariant (1 thread or 16, identical output) - so content-addressed dedup and cache keys stay stable.

Compatibility

Bit-exact on the wire.

  • - RFC 8478 frame format — any libzstd / ruzstd / zstd-cli consumer accepts TurboZstd output unchanged.
  • - Real Niantic SPZ point-cloud payloads (hornedlizard, racoonfamily) compress at L3 and round-trip byte-for-byte through the reference libzstd - validated every run.
  • - Per-level single-thread size (aggregate): ~5% smaller at L1, ~2.3% smaller at L9, parity through L3-L5; L19/L22 a few percent larger - the trade for several-fold encode speed.
  • - Every sample in the 804-sample corpus round-trips cleanly via the reference libzstd; zero failures across AVX2 + NEON, single-thread + multi-thread.
  • - ISAs: AVX2 (x86_64) and NEON (ARM64), each benchmarked on its own native hardware with full per-ISA result artefacts.

libzstd.
Just faster, safer.

Existing pipelines, existing data, existing tooling. Swap the implementation, keep everything else.

Back to Suite

Zstandard, zstd, and libzstd are products of Meta Platforms, Inc. References here identify the products and formats being compared; no affiliation, sponsorship, or endorsement is implied. libzstd is published by Meta under a dual BSD-3-Clause / GPLv2 license. The Zstandard frame format is openly specified in RFC 8878 (which obsoletes RFC 8478) and freely usable. TurboZstd is an independent, clean-room implementation of that specification. Performance comparisons reflect our own measurements under the stated methodology; results vary by workload and hardware.