mbrotli
Brotli compression in safe Rust, with qualities 0–11, reusable encoder storage, streaming I/O, and caller-scheduled parallel compression. This crate provides compression only; it does not include a decoder.
Benchmark results
Median across all eight datasets, with each dataset weighted equally after normalizing to Google C Brotli. Higher speed and lower output are better; 1× matches C. Qualities with the strongest mbrotli median speed / C appear first. Cold serial APIs, window 22, i7-13700KF / WSL2; recorded 2026-09-07. Burli supports q0–q5. Equal quality does not imply equal output size.
Explore the median results, dataset charts, and measurement method and raw data.
Getting started
Requires Rust 1.89 or later.
[]
= "0.1"
use ;
Set the quality explicitly to control compression effort.
EncoderConfig::default() uses quality 11, the most expensive search.
| Quality | Encoding |
|---|---|
| 0–1 | Fast fragment encoding with one or two passes |
| 2–5 | Greedy matching, with block splitting and literal contexts at higher qualities |
| 6–9 | Progressively deeper greedy matching |
| 10–11 | Binary-tree matching and dynamic programming |
Choosing an API
A Compressor owns reusable working buffers. Encoding takes &mut self;
reuse the same compressor for successive streams.
| Need | API |
|---|---|
| Compress into a new vector | compress |
| Append to an existing vector | compress_into |
| Write into a fixed slice | compress_to_slice |
Push input through std::io::Write |
writer |
Pull compressed bytes through std::io::Read |
reader |
| Drive incremental input and output directly | start → EncoderSession |
| Compress with a prepared dictionary | Corresponding *_with_dictionary* methods |
| Split one input across workers | compressor::parallel::ParallelCompressor |
For repeated operations, reuse both the compressor and the destination:
use ;
Streaming
Call finish to terminate a writer's stream and recover its sink.
Dropping the writer does not finish it. flush makes accepted input decodable
without ending the stream; flush boundaries can affect compressed size.
use FinishError;
use ;
use Write;
All serial APIs emit identical bytes with the same configuration, dictionary,
declared input size, flush boundaries, and continuation offset. To match a
one-shot call, use InputSize::Exact(input.len() as u64), offset zero, and
no explicit flushes. Caller chunk sizes and available SIMD backends do not
change the output.
Parallel compression emits one stream from independent segments. Its output is deterministic across task counts for fixed segment settings, but can differ in both bytes and size from serial compression.
Dictionaries and format support
| Feature | Availability |
|---|---|
| Standard Brotli (RFC 7932) | Qualities 0–11 |
| Large Window Brotli | Qualities 3–11; declared windows of 10–62 bits, retained history capped at 30 bits |
| Prepared LZ77 prefix dictionaries | Qualities 5–11; immutable and shareable between compressors |
| Serialized dictionaries and custom static dictionary encoding | experimental feature; compression at qualities 5–11 |
| Headerless stream continuations | experimental feature; qualities 2–11 |
| Shared Brotli framing container writer | experimental feature |
Unsupported quality/feature combinations return errors. A decoder needs the same external dictionaries to decode a stream that references them. The experimental API may change in a patch release.
[]
= { = "0.1", = ["experimental"] }
The encoder is a port of Google's Brotli v1.2.0, pinned in the repository's
brotli-ffi/vendor/brotli submodule at 028fb5a. Tests compare ordinary
output with equivalent C streaming settings and decode it with C. Native C
one-shot shortcuts and arbitrary C chunk schedules can produce different bytes.
Custom static search and framing have separate compatibility checks.
Declared windows above 30 bits lack an independent end-to-end decoder check in
this repository.
Correctness
Each claim this crate makes about its bytes is checked by a machine against an
oracle it does not own: the pinned C encoder for the bytes, the C decoder for
validity, and the crate's own alternative paths for internal agreement. The
correctness proof states every claim, names the oracle
that checks it, and records one complete run of all of them, over both the
standard and the experimental flow, with the commands to repeat it.
| Layer | Latest run, 2026-09-07 |
|---|---|
| Byte identity | Qualities 0–11 and windows 10–24 match Google Brotli v1.2.0 under equivalent streaming settings, over structural, boundary, vendor and randomised corpora |
| Independent decoding | Standard, Large Window, dictionary, parallel and RFC 9841 streams decode with the C decoder |
| Internal identity | Every entry point, chunk schedule, SIMD backend and reuse pattern emits the same bytes |
| Memory | #![forbid(unsafe_code)] outside tests, plus Miri and AddressSanitizer over retained storage and streaming state |
| Coverage | 2259 of 2259 functions executed by the test suite, gated at 100% |
| Fuzzing | 44 AFL++ workers across both feature builds for two hours: 24.3 million executions, no crash, hang or timeout |
The proof also states its limits: a defect shared with Google Brotli v1.2.0 would not be detected, byte identity is claimed only for equivalent C streaming settings, and fuzzing is evidence for the inputs it executed.
Documentation
- User guide: configuration, buffers, streaming, and errors.
- Dictionaries and extended formats: preparation, limits, and experimental features.
- Parallel compression: task scheduling, input sources, and staging.
- Benchmark results: median comparisons and vertical speed/size charts by quality and dataset.
- Benchmarks and profiling: workloads and reproducible commands.
- Correctness proof: every claim, the oracle that checks it, and one complete run of all of them.
- Development: build, checks, coverage, and fuzzing.
- Architecture: implementation mechanics and diagrams.
Runnable examples: