# Aqueous: 이미 압축된 파일을 더 작게 보관하기
# Aqueous: storing already compressed files in less space

- Site: https://select1.dev/2026-10-29 (English), https://select1.dev/ko/2026-10-29 (Korean)
- Entry: 019
- Published: 2026-10-29 (KST). Launch date: 2026-10-28
- Pick: Aqueous <https://github.com/lifthrasiir/aqueous> (source: Show HN)
- Verified: ran
- What: Aqueous 는 이미 압축된 파일을 한 번 더 압축하는 프로덕트다. JPEG, PNG, ZIP 같은 파일의 압축을 풀고, 형식마다 다른 방식으로 다시 압축한다. 압축한 결과는 여러 파일을 하나로 묶은 아카이브 파일에 담긴다. 아카이브를 풀면 원본과 모든 비트가 같은 파일이 나온다.
- What (en): Aqueous is a product that compresses files that are already compressed. It undoes the compression inside files such as JPEG, PNG and ZIP, and compresses the contents again in a way suited to each format. The results go into an archive, one file that holds many files. Extracting the archive gives back files identical to the originals, bit for bit.
- Why: 오늘의 픽으로 선정한 이유는 사진처럼 잘 줄지 않던 파일도 더 작게 보관할 수 있게 하기 때문이다. 화질은 조금도 낮아지지 않는다.
- Why (en): It is today’s pick because it stores hard-to-shrink files like photos in less space. Their quality stays exactly the same.
- Verdict: 작동한다. 압축한 파일을 모두 원본과 비트 단위로 같게 복원했다.
- Verdict (en): It works. Every file it compressed came back bit for bit.
- Tags: compression, archive, rust, webassembly, ai-built

## Checked against the README

- [pass] 압축을 풀면 원본 파일을 비트 단위로 그대로 복원한다(rebuilds the original files bit for bit on extraction) — JPEG 22개, PNG 14개, gzip 20개, SQLite 2개, ZIP 1개, PDF 1개, 합계 6.56 MB 를 압축한 뒤 풀었다. 파일 60개의 SHA-256 이 원본과 모두 같았다
- [pass] 압축 해제 프로그램은 아카이브에 든 WebAssembly 모듈로 파일을 복원하므로, 안에 든 형식을 몰라도 된다(A decompressor needs no knowledge of the formats inside) — --wasm 으로 모든 모듈을 WebAssembly 로 실행해 풀어도 파일 60개의 SHA-256 이 같았다. aqr 에 내장되지 않은 모듈을 샌드박스에서 실행하는 경우는 시험하지 않았다
- [pass] PNG 와 JPEG 은 zstd -3 보다 작게 압축된다(README 표: PNG 0.802 대 0.997, JPEG 0.785 대 0.913) — PNG 14개는 원본 크기의 70.8%(zstd -3 97.9%), JPEG 22개는 70.4%(zstd -3 77.3%)로 줄었다. 이 비율에는 아카이브에 든 모듈의 크기도 포함된다. 비교한 zstd 압축률은 형식마다 tar 로 따로 묶어 압축한 값이다. 이 JPEG 들이 zstd 로도 줄어든 이유는 확인하지 못했다

## Measured

- 파일 60개(6.56 MB)를 압축한 크기. aqr 기본 수준(mid), tar 로 묶은 뒤 zstd -3, tar 로 묶은 뒤 xz -9: 4.63 MB(70.6%), 5.61 MB(85.5%), 5.36 MB(81.8%) (aqr 은 aqr -c -v 가 출력한 요약. zstd -3 과 xz -9 는 tar 로 묶은 파일을 Python 의 zstandard 0.25 패키지(레벨 3)와 lzma 모듈(프리셋 9)로 압축한 결과)

## 한국어

## 무엇이 문제인가

사진, 스크린샷, 문서 파일은 대부분 저장할 때 이미 압축된다. JPEG 은 손실 압축 뒤 마지막 단계에서 허프만 부호화로, PNG 와 ZIP 은 DEFLATE로 압축된다. 압축된 데이터에는 반복되는 패턴이 적어서, 이런 파일을 다시 압축해도 크게 줄지 않는다.

7-Zip 의 7z 형식 문서에 따르면 7z 는 LZMA2 같은 범용 압축 방식에, 실행 파일과 WAV 파일을 위한 변환 필터를 더해 압축한다. 이 문서의 필터 목록에는 JPEG 이나 PNG 처럼 이미 압축된 파일을 위한 필터가 없다. 제작자는 README 에서 Aqueous 를 tar 와 zstd의 조합, 압축 프로그램 zpaq 와 비교했고, 7z 와는 비교하지 않았다. 7z 는 이런 파일의 압축된 바이트를 그대로 다시 압축하므로, 이미 압축된 부분은 크게 줄이지 못한다.

## 어떻게 해결했나

Aqueous 는 2026년 10월 28일 Hacker News 에 Show HN 글로 올라왔다. Aqueous 의 압축 프로그램 aqr 은 파일의 형식을 판별해 파일 안의 압축을 먼저 푼다. 푼 내용물은 형식에 맞춘 압축 모델로 다시 압축한다. README 에 따르면 aqr 은 JPEG, PNG, MP3, PDF, SQLite, ZIP, gzip 등 20여 개 형식을 이렇게 처리한다.

같은 데이터라도 압축기와 설정에 따라 압축된 바이트가 달라진다. 그래서 내용물만 저장하면 원본 파일을 똑같이 만들 수 없다. aqr 은 원래 압축기가 내린 선택(DEFLATE 라면 반복 문자열을 앞의 어느 위치로 가리킬지, 블록을 어디서 나눌지)을 예측하고, 예측이 빗나간 부분만 따로 기록한다. 압축을 풀 때는 이 기록으로 원래 압축 과정을 재현해, 원본과 모든 비트가 같은 파일을 만든다.

아카이브에는 파일마다 복원 절차를 담은 작은 프로그램과, 그 절차에 필요한 WebAssembly 모듈이 함께 들어간다. README 에 따르면 aqr 은 실행 파일에 내장된 모듈을 네이티브 코드로 실행하고, 내장되지 않은 모듈은 샌드박스에서 실행한다.

## 무엇이 다른가

첫째, 압축하는 대상이 다르다. 7z 는 파일의 바이트를 그대로 압축한다. Aqueous 는 파일 안의 압축을 풀고, 그 내용물을 형식별 모델로 압축한다. 압축을 푼 이미지나 텍스트에는 압축된 바이트보다 반복되는 패턴이 많아 더 작게 압축할 수 있다. 다만 원래 압축기의 선택을 잘 예측할 수 있는 파일에만 효과가 있다. 예측이 많이 빗나가면 기록이 커져 이득이 사라진다. 저장소의 aqr-flate 문서에 따르면 aqr 은 DEFLATE 스트림의 경우 zlib 같은 알려진 압축기를 모방해 선택을 예측한다. 예측이 빗나간 부분의 기록이 클 것으로 추정되면, 그 스트림은 풀지 않고 그대로 저장한다.

둘째, 압축 해제 프로그램이 알아야 하는 것이 다르다. 7z 를 풀려면 프로그램이 LZMA2 같은 방식을 미리 구현하고 있어야 한다. Aqueous 는 복원에 필요한 모듈을 아카이브에 넣는다. README 에 따르면 그 덕분에 압축 해제 프로그램은 안에 든 파일 형식을 몰라도 된다. 트레이드오프는 모듈의 크기가 아카이브마다 더해진다는 점이다. 파일이 적은 아카이브는 거의 줄지 않거나 원본보다 커질 수 있다.

제작자는 README 에서 2026년 10월 27일의 측정 결과를 밝혔다. 제작자는 Apple M4 에서 10 GB 벤치마크 데이터(파일 79,431개)를 압축했다. 이 벤치마크는 zpaq 를 만든 Matt Mahoney 가 공개했다. aqr 은 2.63 GB, zpaq 7.15 는 3.70 GB 였다. tar 로 묶은 뒤 zstd -3 으로 압축한 결과는 4.68 GB 였다. 압축에는 aqr 이 136초, zstd 가 33초 걸렸다. aqr 의 시간에는 모든 파일을 복원해 확인하는 과정이 포함된다.

## 어떻게 만들었나

- 커밋 539개는 2026년 10월 5일부터 10월 29일까지 작성됐다. 그중 31개에 Claude 와 함께 작성했다는 Co-authored-by 트레일러가 있다.
- 제작자는 README 에서 LLM 코딩 에이전트를 많이 사용했다고 밝혔다. README 에 따르면 아이디어와 목표는 제작자가 결정했고, 구현과 실험은 AI 가 진행했다.
- 소스 코드는 Rust 99,033줄, 테스트 코드는 11,298줄이다. 형식별 재압축기는 Rust 패키지 24개로 나뉘어 있다.

## 실행해 보니

저장소를 클론해 aqr 을 빌드하고, 파일 60개(6.56 MB)를 압축하고 풀었다. 이 사이트의 스크린샷 JPEG 22개, PNG 14개, Debian 문서의 gzip 20개, SQLite 2개, ZIP 1개, PDF 1개다. PNG 14개 가운데 10개는 그 JPEG 스크린샷을 PNG 로 다시 저장한 것이고, 4개는 실행한 컴퓨터의 node_modules 와 /usr/share 폴더에 있던 것이다.

1. 빌드. README 대로 `cargo build -r -p aqr` 를 실행하자 `flate-zoo/Cargo.toml` 을 읽지 못한다는 에러로 멈췄다. flate-zoo 는 git 서브모듈인데, README 의 빌드 방법에는 서브모듈을 받는 단계가 없다. `git submodule update --init` 을 실행한 뒤에는 4코어 컴퓨터에서 빌드에 7분 40초가 걸렸다. 실행 파일은 166 MB 였다.
2. 압축. 6.56 MB 가 0.98초 만에 4.63 MB(원본 크기의 70.6%)가 됐다. 같은 파일을 tar 로 묶어 압축하자 zstd -3 은 85.5%, xz -9 는 81.8% 였다. xz 는 7z 가 기본으로 사용하는 LZMA2 로 압축한다.
3. 형식별. 형식마다 아카이브를 따로 만들자 PNG 는 70.8%(zstd -3 97.9%), JPEG 은 70.4%(zstd -3 77.3%)가 됐다. SQLite 는 13.1% 로 zstd -3(7.5%)보다 컸다.
4. 복원. `aqr -d` 로 푼 파일 60개의 SHA-256 이 원본과 모두 같았다. 모든 모듈을 WebAssembly 로 실행하는 `--wasm` 으로 풀어도 같았다. 압축 해제 시간은 기본 실행이 0.25초, `--wasm` 이 1.47초였다.
5. gzip. 기본 수준에서는 Debian 문서의 gzip 20개 가운데 18개를 풀지 않고 그대로 저장했다. 시험한 파일 60개와 별도로 GNU gzip 과 Python 의 zlib 으로 gzip 6개를 직접 만들었다. aqr 은 직접 만든 gzip 6개도 모두 그대로 저장했다. 출력에는 그 이유가 나오지 않았다. `-l high` 로 압축하자 aqr 은 6개 가운데 소스 코드를 담은 2개를 풀어서 다시 압축했다.
6. 작은 아카이브. JPEG 하나(131.8 KB)만 압축하자 이미지 데이터는 66.1% 가 됐지만, 모듈과 헤더 41.5 KB 가 더해져 아카이브는 128.6 KB 였다. ZIP 하나(200.6 KB)는 245.2 KB 로 커졌다.

```
/tmp/run/out/corpus.aqr: 60 files, 6.56 MB -> 4.63 MB (70.6%) in 0.98 s, 6.7 MB/s
/tmp/run/one/2026-10-11-2.jpg: jpeg, jpeg-recons@2, 131.8 KB -> 87.2 KB (66.1%)
archive overhead (header, modules, metadata): 41.5 KB
/tmp/run/out/one.aqr: 1 file, 131.8 KB -> 128.6 KB (97.6%) in 0.03 s, 3.8 MB/s
```

## 확인하지 못한 것

- MP3, FLAC, PDF 의 재압축. aqr 은 시험한 PDF 의 형식을 인식하지 못하고 그대로 저장했다. 여러 PDF 와 음악 파일로 압축률을 확인하자.
- 10 GB 벤치마크. 제작자의 결과를 재현하려면 10 GB 데이터를 받아 압축해야 한다. 압축 시간과 복원할 때의 메모리 사용량을 확인하자.
- 샌드박스. README 에 따르면 aqr 에 내장되지 않은 모듈은 권한이 제한된 별도 프로세스에서 실행된다. 그런 모듈을 넣은 아카이브로 모듈의 권한이 실제로 제한되는지 확인하자.

## 판정

작동한다. 압축한 파일을 모두 원본과 비트 단위로 같게 복원했다. 다만 복원 모듈이 아카이브마다 들어가, 파일이 적은 아카이브는 거의 줄지 않거나 오히려 커졌다. 이미 압축된 사진과 스크린샷이 많은 폴더를 백업하면서, zstd 보다 압축 시간이 길어도 용량을 줄이고 싶은 경우에 써 볼 만하다.

### 용어

- 손실 압축: 눈이나 귀로 알아채기 어려운 정보를 버려 크기를 줄이는 압축이다. 버린 정보는 되살릴 수 없다. JPEG 이 대표적이다.
- 허프만 부호화: 자주 나오는 값에 짧은 비트열을, 드문 값에 긴 비트열을 할당해 데이터를 줄이는 부호화 방식이다.
- DEFLATE: 반복되는 문자열을 앞에 나온 같은 문자열의 위치와 길이로 바꾸고, 그 결과를 허프만 부호화로 다시 줄이는 압축 방식이다.
- zstd: Meta 가 공개한 범용 압축 방식이자 프로그램이다. 압축과 해제가 빠르다.
- 압축 모델: 앞에 나온 데이터로 다음 값을 예측하는 압축기의 구성 요소다. 예측이 정확할수록 그 값은 적은 비트로 저장된다.
- WebAssembly: 브라우저와 여러 런타임에서 같은 방식으로 실행되는 바이너리 형식이다. WebAssembly 모듈을 실행하는 프로그램은 그 모듈의 접근 권한을 제한할 수 있다.
- 네이티브 코드: CPU 가 바로 실행하는 기계어로 된 코드다. 중간 형식을 해석하거나 번역하며 실행하는 코드보다 빠르다.
- 샌드박스: 프로그램이 파일, 네트워크 같은 시스템 자원에 접근하지 못하게 제한한 실행 환경이다.
- DEFLATE 스트림: DEFLATE 로 압축된 데이터 한 덩어리다. gzip, PNG, ZIP 파일 안에는 이런 덩어리가 하나 이상 들어 있다.
- SHA-256: 데이터에서 256비트 값을 계산하는 해시 함수다. 값이 같은 파일은 내용이 같다고 본다.

## English

## The problem

Most photos, screenshots and documents are already compressed when they are saved. JPEG ends with Huffman coding after its lossy steps, and PNG and ZIP use DEFLATE. Compressed data has few repeated patterns. So these files do not shrink much when you pack them again with an archiver.

The README compares Aqueous with tar plus zstd and with the zpaq archiver. It does not include 7z. According to 7-Zip’s page on the 7z format, 7z compresses with general-purpose methods such as LZMA2. It adds conversion filters for executables and WAV files. The page lists no filter for JPEG or PNG, which hold compressed data inside. So 7z compresses the bytes of these files as they are, and the compressed parts do not shrink much.

## How it solves it

Aqueous was posted as a Show HN on Hacker News on October 28, 2026. Its archiver, aqr, detects a file’s format and undoes that format’s compression. It then compresses the contents again with a compression model made for that format. According to the README, it handles about twenty formats this way, including JPEG, PNG, MP3, PDF, SQLite, ZIP and gzip.

The same data gives different compressed bytes with different compressors and settings. So the contents alone are not enough to rebuild the original file. aqr predicts the choices the original compressor made and records only the ones it got wrong. For DEFLATE, the choices are which earlier string each repeat points to and where blocks split. On extraction it replays the original compression with that record and rebuilds the file bit for bit.

Each archive holds a small rebuild program for each file, plus the WebAssembly modules those programs use. According to the README, aqr runs the modules built into its binary as native code. It runs other modules in a sandbox.

## What is different

The first difference is what gets compressed. 7z compresses a file’s bytes as they are. Aqueous undoes the compression inside the file and compresses the contents with a model for that format. The decoded image or text shows far more repetition and structure than the compressed bytes. But this helps only when aqr can predict the original compressor’s choices well. When many guesses miss, the record grows and the gain disappears. According to the aqr-flate notes in the repository, aqr predicts the choices in a DEFLATE stream by emulating known compressors such as zlib. When it expects the record of wrong guesses to be large, it stores the stream as it is.

The second difference is what the extractor must know. To open a 7z archive, a program must already implement methods such as LZMA2. Aqueous puts the modules it needs into the archive. So, according to the README, the extractor does not need to know the formats inside. The tradeoff is that the modules add size to every archive. An archive with few files may barely shrink, or end up larger than the input.

In the README, the maker reports a run from October 27, 2026. It compressed the 10 GB benchmark (79,431 files) published by Matt Mahoney, who wrote zpaq, on an Apple M4. aqr produced a 2.63 GB archive, and tar with zstd -3 produced a 4.68 GB archive. zpaq 7.15 produced a 3.70 GB archive. aqr took 136 seconds and zstd took 33 seconds. aqr’s time includes rebuilding every file to check it.

## How it was built

- The 539 commits date from October 5 to October 29, 2026. Of these, 31 have a Co-authored-by trailer for Claude.
- In the README, the maker says the project makes heavy use of LLM coding agents. The maker provided the ideas and goals, and the agents wrote the code and ran the experiments.
- The source is 99,033 lines of Rust, and the tests are 11,298 lines. The per-format recompressors are split into 24 Rust packages.

## Running it

I cloned the repository and built aqr. I then compressed and extracted 60 files (6.56 MB). They included 22 JPEG screenshots from this site and 14 PNG files. Ten of the PNG files were those screenshots saved again as PNG, and four came from the node_modules and /usr/share folders on the machine I used. The rest were 20 gzip files from Debian docs, 2 SQLite files, 1 ZIP and 1 PDF.

1. Build. The README’s command, `cargo build -r -p aqr`, failed because it could not read `flate-zoo/Cargo.toml`. After `git submodule update --init`, the build took 7 minutes 40 seconds on a 4-core machine. The binary was 166 MB.
2. Compression. aqr compressed the 60 files from 6.56 MB to 4.63 MB (70.6% of the original size) in 0.98 seconds. In a tar archive, the same files came to 85.5% with zstd -3 and 81.8% with xz -9. xz uses LZMA2, the default method of 7z.
3. By format. With a separate archive per format, PNG came to 70.8% (zstd -3: 97.9%), and JPEG came to 70.4% (zstd -3: 77.3%). SQLite came to 13.1%, larger than zstd -3 (7.5%).
4. Extraction. All 60 files extracted with `aqr -d` had the same SHA-256 hash as the originals. They also matched with `--wasm`, which runs every module as WebAssembly. Extraction took 1.47 seconds with `--wasm` and 0.25 seconds without it.
5. gzip. At the default level, aqr stored 18 of the 20 Debian gzip files as they were. Apart from the 60 test files, I made 6 gzip files with GNU gzip and Python’s zlib. aqr stored all of them as they were, and its output did not say why. With `-l high`, it unpacked and recompressed the two files that held source code.
6. Small archives. For one JPEG (131.8 KB), aqr compressed the image data to 66.1% of its original size. The modules and header added 41.5 KB, so the archive was 128.6 KB. One ZIP (200.6 KB) grew to 245.2 KB.

```
/tmp/run/out/corpus.aqr: 60 files, 6.56 MB -> 4.63 MB (70.6%) in 0.98 s, 6.7 MB/s
/tmp/run/one/2026-10-11-2.jpg: jpeg, jpeg-recons@2, 131.8 KB -> 87.2 KB (66.1%)
archive overhead (header, modules, metadata): 41.5 KB
/tmp/run/out/one.aqr: 1 file, 131.8 KB -> 128.6 KB (97.6%) in 0.03 s, 3.8 MB/s
```

## Not checked

- MP3, FLAC and PDF recompression. aqr did not recognize the PDF I tested and stored it as it was. Check the ratios on more PDF and music files.
- The 10 GB benchmark. Reproducing the maker’s result requires a 10 GB download. Check the compression time and the memory use during extraction.
- The sandbox. According to the README, modules not built into aqr run in a separate process with limited permissions. Test it with an archive that holds such a module.

## Verdict

It works. Every file it compressed came back bit for bit. But the rebuild modules go into every archive, so an archive of a few files was barely smaller than the original files, or even larger. It is worth trying if you back up folders full of photos and screenshots that are already compressed. You also need to accept slower compression than zstd in exchange for less space.

### Terms

- Huffman coding: A coding method that gives short bit strings to frequent values and long ones to rare values, so the data takes fewer bits.
- lossy compression: Compression that makes data smaller by dropping details people are unlikely to notice. The dropped details cannot be restored. JPEG is the best-known example.
- DEFLATE: A compression method that replaces a repeated string with the position and length of an earlier copy, then applies Huffman coding. ZIP, gzip and PNG use it.
- zstd: A general-purpose compression method and tool released by Meta. It compresses and decompresses quickly.
- compression model: The part of a compressor that predicts the next value from earlier data, so values it predicts well take fewer bits.
- WebAssembly: A portable binary format for code that browsers and other runtimes can run. The host can limit what the code can access.
- native code: Code in the machine language that the CPU runs directly. It runs faster than code that has to be interpreted or translated first.
- sandbox: An environment that runs a program while blocking its access to system resources such as files and the network.
- DEFLATE stream: One continuous piece of data compressed with DEFLATE. gzip, PNG and ZIP files hold one or more of them.
- SHA-256: A hash function that computes a 256-bit value from data. Files with the same value are taken to have the same content.

## Launches the same day

- Nasscad <https://www.nasscad.com/NASSCAD_V4_7_0.htm> (Show HN, 23): 3D CAD 앱. 브라우저와 Windows 에서 무료로 사용하고, 로컬 우선으로 작동한다고 소개한다.
- GEAR <https://rsi-gear.github.io/> (Show HN, 18): LLM 에이전트 하네스의 재귀적 자기 개선 프레임워크. 연구 논문과 함께 공개했다.
- Yavashark <https://yavashark.dev/blog/announcing-yavashark/> (Show HN, 12): JavaScript 엔진. 제작자는 950일 동안 매일 작업했다고 밝혔다.
- Popkern <https://popkern.dev/> (Show HN, 9): 오픈소스 CAD 커널. 코드로 부품을 설계하고 브라우저 IDE 에서 편집한다.
- plushies <https://prathje.github.io/plushies/> (Show HN, 9): 웹용 3D 캐릭터. Three.js 로 봉제 인형처럼 렌더링한다.
- Aqueous <https://github.com/lifthrasiir/aqueous> (Show HN, 4): 아카이브 형식과 압축 프로그램. 이미 압축된 파일을 다시 압축하고 원본 그대로 복원한다.
- tongjiang-lab <https://github.com/smithjohn78390/tongjiang-lab> (GitHub, 446): 고등학교 과학 3D 수업 54개. 수업마다 HTML 파일 하나라 오프라인에서도 열린다.
- open-yoki <https://github.com/jacke-pp/open-yoki> (GitHub, 202): AI 라이브 방송 진행자. 서버 하나로 음성, 얼굴, 채팅, 기억을 운영한다.
- mcode-stack <https://github.com/MiniMax-AI/mcode-stack> (GitHub, 170): MiniMax Code 팀의 워크플로와 스킬 모음. 설치해 사용할 수 있게 공개했다.
- Dedica <https://www.producthunt.com/products/dedica> (Product Hunt, 249): 웹사이트 점검 도구. AI 에이전트가 사이트를 사용할 수 있는지 확인한다고 소개한다.
- bytemail <https://www.producthunt.com/products/bytemail> (Product Hunt, 225): macOS 메일 앱. 모든 받은편지함을 노치에 모으고 추적기를 막는다고 소개한다.
- BotGauge <https://www.producthunt.com/products/botgauge-2> (Product Hunt, 204): 에이전트 점검 도구. 제작자는 에이전트를 위한 신뢰 계층이라고 소개한다.

## Getting started

- Steps: git submodule update --init ; cargo build -r -p aqr
- Needs: Rust 와 cargo
- Cost: 퍼블릭 도메인(퍼블릭 도메인을 인정하지 않는 나라에서는 MIT-0), 무료.
- Note: README 의 빌드 방법에는 서브모듈을 받는 단계가 없어, 클론한 뒤 git submodule update --init 을 먼저 실행해야 한다. 아카이브 형식의 명세는 아직 초안이다.
