Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Zstandard compression and decompression in safe Rust

mzstd is a port of the zstd 1.5.7 encoder that writes the same bytes, plus an independent Rust decoder. Reuse working memory between payloads, plug into Read and Write, drive either codec with your own buffers, and schedule parallel compression on your own threads.

A round trip

[dependencies]
mzstd = "0.2.13"
use mzstd::{Compressor, Decompressor, EncoderConfig, Level};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input = "hello, smaller world! ".repeat(1000);
    let mut encoder = Compressor::new(EncoderConfig::default().with_level(Level::try_from(3)?))?;
    let compressed = encoder.compress(input.as_bytes())?;

    let mut decoder = Decompressor::default();
    assert_eq!(decoder.decompress(&compressed)?, input.as_bytes());
    Ok(())
}

Requires Rust 1.89 or later. Getting started continues from here with memory reuse, streaming and feature selection.

Pick a level

The level trades speed for size; the default is 3. Each bar is the compressed size of the 211 MB Silesia corpus against its original size.

LevelCompressed sizeCompressDecompress
-548.6%838 MB/s2828 MB/s
134.5%626 MB/s1992 MB/s
331.2%374 MB/s1784 MB/s
828.2%103 MB/s1945 MB/s
1526.8%9.04 MB/s2014 MB/s
2224.7%2.27 MB/s1498 MB/s

mzstd 0.2.12 in lzbench 2.4.1 on one thread of an AMD Ryzen 9 7950X VDS, fastest of three rounds. Your data and machine will differ.

See the lzbench run for the command and raw output, and benchmark results for every measured level against zstd 1.5.7, including the cases where mzstd is slower.

Find your path

What you can rely on

  • Byte-identical encoder. For the same input and parameters, serial compression writes exactly the bytes of zstd 1.5.7. See what is claimed and how it is checked.
  • Safe implementation, not a C wrapper. Production code forbids unsafe; SIMD goes through fearless_simd. The reference C library is only a test and benchmark oracle.
  • No hidden I/O or threads. Sessions touch only the buffers you pass in, and parallel compression hands tasks to your scheduler. The library does not create a thread pool.
  • Reusable state. A codec keeps its workspace between payloads, under a retention policy you choose.

Framing requires the opt-in framed feature; its API may change in a patch release.