HatchZip's Truncation Trick Extracts a 2.2GB Archive in 300MB of Free Space
Developers extracting large packages on nearly full disks no longer need to free up double the archive's size; HatchZip requires only space for one file plus a configurable reserve. The trade-off is that the original archive is consumed by default, and the space benefit vanishes when the disk has plenty of headroom.
HatchZip 0.1.8, an MIT/Apache-2.0 dual-licensed decompressor written in Rust, extracts a 2.2GB ZIP in 6.97 seconds while capping disk usage at 2,412MB when available space is forced down to 300MB via `--keep-free`. It does this by starting from the end of the archive and truncating each committed batch, freeing the space for subsequent output. The mechanism requires the ZIP central directory tail to be saved as a separate file and kept in memory (up to 1GB), a strict commit order (flush, journal, then truncate), and batch sizes that adapt to available space minus the reserved `--keep-free` amount.
On a wide disk with roughly 34GB free, HatchZip's peak usage is nearly identical to normal `unzip` (4,429MB vs 4,404MB), so its space saving appears only under disk pressure. When the budget falls below the size of the largest file in the archive, it refuses cleanly with exit code 3, leaving the archive and output untouched. It supports resuming after budget exhaustion if the next run gets enough space, and it rejects path traversal before doing anything else.
The test archive was synthetic (21 × 100MiB random files), so real-world packages with many small files may hit the 512-file batch limit instead of the byte cap. HatchZip defaults to deleting the original archive on success, and the safe budget depends entirely on the size of the largest file; any change to the archive requires re-running `check`.
The space saving is conditional on batch size, which is determined by available space minus `--keep-free`; on a large disk, HatchZip behaves like a normal unzip with a small overhead from tail copying and journaling.
HatchZip's failure mode is notably clean: it refuses before modifying anything, and even the journal is absent when the budget floor isn't met.
The test used equal-sized files that align perfectly with batch boundaries; real archives with many small files will hit the 512-file batch limit, changing truncation frequency and metadata overhead in ways not covered by this source.
A truly full disk was not simulated; the 300MB budget was created by `--keep-free`, so physical disk fragmentation and allocation behavior remain an open question.
The choice between `--keep-archive` and space saving is binary; there's no way to keep the archive and still benefit from in-place truncation.