Aqueous

The files you keep are already compressed. Badly.

Aqueous is an archive format and an archiver, aqr, built around lossless recompression. It undoes the weak compression inside JPEG, PNG, MP3, ZIP, PDF and dozens more, codes the contents with stronger models, and rebuilds the original files bit for bit on extraction.

Windows, macOS and Linux. Public domain.

Recompression, not just compression

General-purpose compressors see a JPEG or a ZIP as noise and leave it be. Aqueous looks inside, and the archive keeps everything needed to give back exactly the bytes it was given.

Formats of every kind

Huffman codes in JPEG and MP3, deflate in PNG, ZIP, PDF and gzip, LZ4 and Snappy in browser profiles and databases; FLAC and Vorbis, ProRes and Matroska, PSD and DDS textures, SQLite and HDF5, 7z, RAR, LHA and ISO images, executables and WebAssembly, and the list keeps growing, each with its own recompressor.

Self-describing archives

A file's content is a formula: a small stack-machine program that applies WebAssembly modules carried in the archive. Any decoder can extract it with no knowledge of the formats inside; known modules run natively, others in a sandbox.

Random access, appendable

A file is extracted by reading little more than its own blocks. Archives grow by appending, and overlay archives describe a tree as the changes to another.

Smaller than the usual suspects

Matt Mahoney's 10 GB benchmark: 79,431 files, 10.00 GB of real-world data, on an Apple M4 with 10 cores.

Archive size

GB, smaller is better

  • tar | zstd -3 -T104.68
    4.68 GB · 33 s to compress
  • zstd -3 --long=314.17
    4.17 GB · 36 s to compress
  • zpaq 7.153.70
    3.70 GB
  • aqr (level mid)2.50
    2.498 GB · 164 s to compress, 38.8 s to extract

aqr compresses at 61 MB/s, round-trip check of every file included, and extracts at 258 MB/s. The archive includes its own decoder modules.

By format
Formataqrzstd -3
JPEG0.778–0.7940.913
PNG0.802–0.8550.997
MP30.852–0.9150.968
PE executables0.295–0.3030.381
SQLite0.210–0.2190.366
Text (enwik9)0.233–0.2350.312
FASTA (hg19)0.2090.309

Archive size over input size, decoder modules included. Of two figures, the first is with the modules shared, as in an archive of many files; the second, each file an archive of its own carrying them. Measured 2026-11-01; details in docs/file-formats.md.

How it works

The archive stores what the original encoder threw away the chance to code well, and the recipe to put it back together.

  1. Recognise

    Each file is matched by its magic bytes to a recompressor, which may recurse into what it finds: a PNG inside a ZIP inside a tarball.

  2. Undo and remodel

    The recompressor decodes the weak coding, records the choices the original encoder made, and hands the contents to stronger context models.

  3. Write a formula

    The file becomes a formula over stored blocks, linking the Wasm modules that rebuild it. Every file is decoded again and checked before the archive is done.

  4. Rebuild exactly

    Extraction runs the formula and gives back the original bytes, bit for bit, without the archiver knowing the format.

# compress a directory into one archive
$ aqr -c -o photos.aqr photos/

# check every file, writing nothing
$ aqr -t photos.aqr

# extract
$ aqr -d photos.aqr

# levels: -l low | mid (default) | high, or -0 … -9
$ aqr -l high -o backup.aqr ~/Documents

Standing on shoulders, built to last

None of the ideas behind Aqueous are new. What it adds is the work of making them something anyone can rely on.

Prior work

Bringing it to everyone

ZPAQ put the decoder in the archive years ago; PAQ, precomp, preflate, packJPG, Lepton and packMP3 showed how far recompression and context modelling can go. Aqueous is not meant as their rival: it is designed to take what they proved and bring it to an archiver people use every day.

Where each idea comes from is listed in CREDITS.md.

Why now

Made possible by modern tools

Zstandard gives a fast, well-specified baseline for every byte that is not recompressed, so the archive never has to fall back to something slow. WebAssembly lets an archive carry its decoders as small, sandboxed, deterministic programs that run anywhere. Rust builds one memory-safe codebase both into those modules and into the native code that runs them faster, so the decoder in the archive is the one in use. Machines with many cores pay for the stronger models.

Commitment

A specification first

The format is defined by a written specification, worked out together with the implementation from the first day rather than documented after it: every structure, every requirement, the execution of every module, and room for future versions to extend it.

An archive that needs only the specification to be read is an archive that outlives its archiver. Archives made by released versions of aqr are meant to stay extractable.

Download

Binaries are on the latest release. The format is still an Editor's Draft. Every archive is decoded and checked before aqr finishes, and archives made now are meant to stay extractable by later versions; until the format is fixed, keep the aqr you made them with alongside them.

Or build from source with Rust: cargo build -r -p aqr in a clone of the repository. All releases are on GitHub.