Measured, not claimed
What ANLA does to real bytes
Five scenarios, run against this repository's own git history and against the alternatives a person would actually reach for. Every figure is produced by bench/run_bench.py and written to a JSON file this page is generated from, so the page cannot say anything the harness did not measure — including the rows where ANLA loses.
One snapshot of this repository's python/ directory
This row used to be the argument for Zstandard, stated as a measurement: with only `store` a single snapshot was larger than the tree and both compressors beat it comfortably. The codec landed, so the row now answers its own question — and the `store` line is kept beside it, because a benchmark that quietly drops the case it used to lose is not reporting, it is marketing. **This row's input is the live repository, so its absolute byte counts are not comparable between commits** — adding four test files moved every size on it, including every competitor's. Only the ratios within one run mean anything across time, and a regression small enough to hide inside a few new files would not be visible here at all. The four scenarios with fixed inputs are where a regression would show, and they are exact: on the run that added this note, not one byte moved on any of them.
ANLA 1.0 (zstd + anla-cdc-1)793.9 KiB
ANLA-MVP (deflate)868.2 KiB
ZIP, deflate -9835.4 KiB
tar.gz -9731.3 KiB
ANLA 1.0, codec turned off2.10 MiB
34% of the input 2.29 MiB
500 files: what namespaced metadata and 500 symlinks add
Milestone 2 moves no compression number, because it is not about compression — it is what lets the tool pack trees it used to refuse outright. This is its actual bill, per object, in the manifest. A symbolic link costs a manifest entry and no chunk at all: it has no content, only a target.
ANLA 1.0 (zstd + anla-cdc-1)329.7 KiB
no_metadata253.5 KiB
times_only271.1 KiB
times_and_mode278.5 KiB
4280% of the input 7.7 KiB
8 successive commits of python/, one snapshot each
Every version is recoverable, byte for byte. The comparison is against keeping each version as its own ZIP, which is what people do without snapshots, and against one tar.gz of all of them — gzip's 32 KB window cannot see from one copy of the tree to the next, which is why deduplication is a different mechanism and not a worse compressor. **This row's input is the live repository, so its absolute byte counts are not comparable between commits** — adding four test files moved every size on it, including every competitor's. Only the ratios within one run mean anything across time, and a regression small enough to hide inside a few new files would not be visible here at all. The four scenarios with fixed inputs are where a regression would show, and they are exact: on the run that added this note, not one byte moved on any of them.
ANLA 1.0 (zstd + anla-cdc-1)390.5 KiB
ZIP per version, deflate -91.50 MiB
tar.gz, all versions at once1.25 MiB
ANLA 1.0, codec turned off825.2 KiB
9% of the input 4.42 MiB
Where the bytes went, per snapshot
New content against the cost of describing it. A manifest describes its whole snapshot rather than a delta, and this is what that costs.
| Snapshot | New content | Metadata |
|---|
| 1 | 173.7 KiB | 17.8 KiB |
| 2 | 7.7 KiB | 18.6 KiB |
| 3 | 4.5 KiB | 18.9 KiB |
| 4 | 8.6 KiB | 19.3 KiB |
| 5 | 6.2 KiB | 19.3 KiB |
| 6 | 24.2 KiB | 21.4 KiB |
| 7 | 3.6 KiB | 21.4 KiB |
| 8 | 3.9 KiB | 21.4 KiB |
The same directory snapshotted 5 times, unchanged
The ceiling. Snapshots 2 to 5 add a manifest and a footer and nothing else, so their cost is the price of decision 1 in the snapshot design: a manifest describes its whole snapshot rather than a delta.
ANLA 1.0 (zstd + anla-cdc-1)127.8 KiB
ZIP per copy, deflate -9233.6 KiB
23% of the input 557.4 KiB
Where the bytes went, per snapshot
New content against the cost of describing it. A manifest describes its whole snapshot rather than a delta, and this is what that costs.
| Snapshot | New content | Metadata |
|---|
| 1 | 112.2 KiB | 3.0 KiB |
| 2 | 0.0 KiB | 3.1 KiB |
| 3 | 0.0 KiB | 3.1 KiB |
| 4 | 0.0 KiB | 3.1 KiB |
| 5 | 0.0 KiB | 3.1 KiB |
2 MB of random bytes, then the identical file again
Nothing compresses this, and nothing should. The first snapshot costs slightly more than the file; the second costs almost nothing, because deduplication does not care whether the bytes are compressible.
ANLA 1.0 (zstd + anla-cdc-1)1.91 MiB
ZIP per copy, deflate -93.82 MiB
tar.gz, both copies3.82 MiB
50% of the input 3.81 MiB
Where the bytes went, per snapshot
New content against the cost of describing it. A manifest describes its whole snapshot rather than a delta, and this is what that costs.
| Snapshot | New content | Metadata |
|---|
| 1 | 1.91 MiB | 3.1 KiB |
| 2 | 0.0 KiB | 3.1 KiB |
3 MB file, then the same file with 64 bytes inserted at the front
The case fixed-size chunking cannot survive: every boundary moves, so not one chunk matches and the whole file is stored twice. Content-defined boundaries follow the content, so only the chunks that actually changed are new.
ANLA 1.0 (zstd + anla-cdc-1)3.14 MiB
ANLA 1.0, fixed chunking5.73 MiB
55% of the input 5.72 MiB
Where the bytes went, per snapshot
New content against the cost of describing it. A manifest describes its whole snapshot rather than a delta, and this is what that costs.
| Snapshot | New content | Metadata |
|---|
| 1 | 2.86 MiB | 3.7 KiB |
| 2 | 277.0 KiB | 3.8 KiB |
64 MiB of incompressible data, packed and verified
MiB per second, on the machine that ran this. Content-defined chunking is the default because fixed chunking destroys deduplication — and in the Python writer it is also the slow path, by two orders of magnitude. The Rust writer produces byte-identical archives at 28 times the rate, so this is an implementation number and not a format number. It is published because a project that measures only what it is good at is not measuring.
Python writer, fixed chunking64.4 MiB/s · 4.52 h/TiB
Python writer, anla-cdc-1 (the default)3.8 MiB/s · 76.65 h/TiB
Python reader, verify538.1 MiB/s
Rust writer, anla-cdc-1107.3 MiB/s · 2.71 h/TiB