Kanzi Compression Levels 0-9: Complete Guide to Trade-offs and Performance
Kanzi compression levels 0 through 9 map to preset combinations of transforms and entropy codecs defined in BlockCompressor::getTransformAndCodec, where higher levels trade speed and memory for superior compression ratios by employing algorithms ranging from simple LZX to complex BWT and TPAQX pipelines.
The flanglet/kanzi-cpp repository implements a tiered compression system where the -l or --level argument selects predefined pipelines. Understanding these Kanzi compression levels is essential for optimizing the balance between throughput, memory consumption, and archive size.
How Kanzi Compression Levels Work
The level system is hard-coded in src/app/BlockCompressor.cpp within the getTransformAndCodec function (lines 21-73). When you specify -l N, the command-line parser in src/app/Kanzi.cpp (lines 94-108) stores the value in the context object. The BlockCompressor constructor then retrieves this value and invokes getTransformAndCodec to determine the specific transform string and entropy codec.
The function returns two strings that are stored in the context as "transform" and "entropy". These strings drive the TransformFactory and entropy codec factories when CompressedOutputStream instantiates the compression pipeline.
Detailed Breakdown of Kanzi Compression Levels 0-9
Each level corresponds to a specific transform pipeline and entropy codec combination:
| Level | Transform Pipeline | Entropy Codec | Typical Use Case | Relative Speed |
|---|---|---|---|---|
| 0 | NONE |
NONE |
Pass-through testing | Fastest (no work) |
| 1 | LZX |
NONE |
Quick-look compression, low-latency pipelines | ~1% of level 9 |
| 2 | DNA+LZ |
HUFFMAN |
Small binary blobs, DNA-style data | ~3% of level 9 |
| 3 | TEXT+UTF+PACK+MM+LZX |
HUFFMAN |
Default for generic files | ~10% of level 9 |
| 4 | TEXT+UTF+EXE+PACK+MM+ROLZ |
NONE |
Avoiding block-checksum overhead | ~20% of level 9 |
| 5 | TEXT+UTF+BWT+RANK+ZRLT |
ANS0 |
Highly repetitive text | ~35% of level 9 |
| 6 | TEXT+UTF+BWT+SRT+ZRLT |
FPAQ |
Large textual corpora | ~55% of level 9 |
| 7 | LZP+TEXT+UTF+BWT+LZP |
CM |
Mixed binary-text workloads | ~70% of level 9 |
| 8 | EXE+RLT+TEXT+UTF+DNA |
TPAQ |
Binaries and DNA-like data | ~90% of level 9 |
| 9 | EXE+RLT+TEXT+UTF+DNA |
TPAQX |
Maximum compression | Reference (slowest) |
The speed percentages derive from empirical benchmarks in the repository README. For example, compressing silesia.tar takes approximately 11,618 ms at level 9 versus 72 ms at level 1.
Performance and Resource Trade-offs
Transform Complexity
Lower levels employ simple dictionary-based transforms like LZX and DNA+LZ. Mid-range levels introduce TEXT and UTF preprocessing filters. High levels activate the Burrows-Wheeler Transform (BWT) in levels 5-7, while levels 8-9 add EXE (executable filters) and RLT (run-length transforms).
Entropy Coding Overhead
The entropy codec selection significantly impacts CPU and memory:
NONE: Zero overhead, direct byte storageHUFFMAN: Fast, low-memory Huffman codingANS0/FPAQ: Asymmetric numeral systems and neural predictive codingTPAQ/TPAQX: Complex context mixing models requiring substantial memory and computation
Memory Considerations
The default block size is 4 MiB (DEFAULT_BLOCK_SIZE in BlockCompressor.cpp lines 38-40). While levels do not automatically alter block size, high levels benefit from larger blocks. You can enable automatic block sizing with --block=AUTO or specify manually (e.g., --block=64M).
Recommendations by Use Case
| Scenario | Recommended Level | Rationale |
|---|---|---|
| Real-time streaming or low-latency services | 0 or 1 | No transform or only fast LZX; negligible CPU overhead |
| General-purpose archiving (speed priority) | 3 (default) | Balanced TEXT+UTF+PACK+MM+LZX with Huffman; ~10% of level 9 time |
| Large text logs, CSV, or source code | 5 or 6 | BWT-based pipelines with ANS0/FPAQ for repetitive text |
| Mixed binary/text bundles | 7 | LZP-enhanced pipeline handles both patterns efficiently |
| Maximum compression (offline backups) | 9 | Full EXE+RLT+TEXT+UTF+DNA with TPAQX; smallest files, 10-20× slower |
| Limited RAM (embedded devices) | 0-3 | Memory usage stays under 50 MiB; higher levels allocate BWT/TPAQX buffers |
| Custom transform experimentation | Manual | Skip -l; use --transform and --entropy directly |
Tip: When using level 9, ensure block size is at least 4 MiB or larger (
--block=64M). The auto-block heuristic (--block=AUTO) selects size proportional to input divided by job count, improving throughput for large files.
Implementation Examples
Command-Line Usage
# Fast compression for low-latency pipelines (level 1)
kanzi -c -i input.bin -o output.knz -l 1
# Default balanced compression (level 3)
kanzi -c -i input.txt -o output.knz
# Maximum compression with multi-threading (level 9)
kanzi -c -i large.tar -o large.knz -l 9 -j 4
Flag handling is implemented in src/app/Kanzi.cpp (lines 94-108 for level parsing).
C++ API Integration
#include "kanzi/api/Compressor.hpp"
#include "kanzi/util/Context.hpp"
int main() {
kanzi::Context ctx;
ctx.putInt("level", 6); // Select level 6 preset
ctx.putInt("jobs", 2); // Enable 2-thread parallelism
ctx.putString("inputName", "data.bin");
ctx.putString("outputName", "data.knz");
kanzi::Compressor comp(ctx); // Selects transform & codec internally
uint64 written = 0;
comp.compress(written); // Returns compressed size in bytes
}
The Compressor constructor (in src/api/Compressor.hpp/.cpp) forwards the context to BlockCompressor, which invokes getTransformAndCodec. The level value is retrieved via ctx.getInt("level") as seen in BlockCompressor::BlockCompressor.
Custom Pipeline Override
kanzi::Context ctx;
ctx.putString("transform", "TEXT+UTF+BWT+RANK+ZRLT"); // Custom pipeline
ctx.putString("entropy", "ANS0"); // Custom codec
// No level set - BlockCompressor skips getTransformAndCodec()
kanzi::Compressor comp(ctx);
When level is omitted, BlockCompressor falls back to the custom strings (see lines 60-74 of BlockCompressor.cpp).
Summary
- Kanzi compression levels 0-9 are hard-coded presets in
BlockCompressor::getTransformAndCodecthat pair specific transform pipelines with entropy codecs. - Level 0 provides pass-through storage, while level 9 employs the most aggressive
EXE+RLT+TEXT+UTF+DNAtransform withTPAQXentropy coding for maximum compression. - Level 3 serves as the default, offering a balance between the
TEXT+UTF+PACK+MM+LZXtransform and fastHUFFMANcoding. - Memory usage scales with level due to BWT buffers and context-modeling requirements; levels 0-3 remain lightweight while levels 8-9 require substantial RAM.
- Custom pipelines bypass the level system entirely by setting
--transformand--entropydirectly in the API or CLI.
Frequently Asked Questions
What is the default Kanzi compression level?
The default level is 3. When you run kanzi -c -i input -o output without specifying -l, the application automatically selects level 3, which uses the TEXT+UTF+PACK+MM+LZX transform pipeline paired with HUFFMAN entropy coding. This preset targets general-purpose files such as text documents and executables while maintaining approximately 10% of the compression time required by level 9.
How do Kanzi compression levels affect memory usage?
Memory consumption increases with compression level primarily due to transform complexity and entropy codec state. Levels 0-3 typically require less than 50 MiB because they use simple LZ variants or no transforms and lightweight codecs like HUFFMAN or NONE. Levels 5-7 allocate additional buffers for the Burrows-Wheeler Transform (BWT), while levels 8-9 require substantial memory for context-mixing models (TPAQ/TPAQX) and multiple transform stages including EXE and RLT filters.
Can I use custom transforms instead of the preset levels?
Yes. You can bypass the level system entirely by specifying the --transform and --entropy arguments directly via CLI, or by calling ctx.putString("transform", ...) and ctx.putString("entropy", ...) in the C++ API. When these strings are provided, BlockCompressor skips the getTransformAndCodec lookup and uses your custom pipeline. This allows experimentation with combinations not covered by the standard 0-9 presets, such as TEXT+UTF+BWT+RANK+ZRLT with ANS0.
What is the performance difference between level 1 and level 9?
Level 1 is approximately 160× faster than level 9 while providing minimal compression. According to benchmark data in the repository README, compressing the silesia.tar corpus takes roughly 72 ms at level 1 versus 11,618 ms at level 9. Level 1 uses only the LZX transform with no entropy codec, making it suitable for real-time streaming, while level 9 employs the full EXE+RLT+TEXT+UTF+DNA transform chain with the TPAQX codec for maximum compression ratio.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →