

Compression that optimises your bill, not your byte count —
and ships the benchmark so you can check it.









How it compares to Alternative A
Providers cache the prompt prefix: cached tokens re-read at 0.1x, rewritten
ones bill at 1.25x. Most compressors optimise bytes removed and ignore that
multiplier. This one optimises the bill.
Measured against their real implementation, on their own fixtures. Not a
reimplementation and not our fixtures: their harness compresses the payload,
dumps it, their resolver redeems their own markers, and ours is handed the
identical bytes. Their column is the best of the nine configurations that
capture holds, row by row.
Two of our arms are in the table, and they answer different questions. ours
is the block engine with nowhere to move a block, which is how the MCP tools and
the hooks run: everything it removes, it removes by compressing, and nothing
leaves the request. ours, proxy is the proxy a Claude Code session runs
through, which also moves a block it could not compress out to a file and
leaves a marker naming the path -- the same kind of trade their content-cache
reference makes. ours, preset is the block engine with that move switched on
at spillWholeBlockBelow: 0.9.
| workload | payload | theirs | ours | ours, proxy | ours, preset | zero-turn ids |
|---|
| agentic-conversation | 244,908 | 37.3% / 33.4% | 42.9% / 30.8% | 52.4% / 49.0% | 100.0% / 100.0% | 2099 / 2099 / 0 |
| agent-loop | 170,938 | 42.2% / 54.3% | 69.3% / 59.1% | 92.0% / 94.1% | 93.6% / 94.3% | 185 / 185 / 52 |
| agent-loop-logs | 327,500 | 51.5% / 53.0% | 61.9% / 58.1% | 88.7% / 91.5% | 96.2% / 97.0% | 2034 / 2034 / 81 |
| api-responses | 49,127 | 88.2% / 89.3% | 66.6% / 59.1% | 96.4% / 96.8% | 96.6% / 96.8% | 699 / 98 / 23 |
| browser-session | 781,774 | 21.7% / 13.1% | 93.7% / 26.5% | 55.5% / 90.2% | 100.0% / 99.9% | 334 / 334 / 0 |
| code-search | 131,264 | 47.4% / 59.7% | 81.8% / 70.8% | 97.7% / 97.9% | 95.7% / 96.1% | 201 / 201 / 43 |
| database-rows | 45,929 | 88.6% / 89.2% | 65.6% / 56.5% | 92.4% / 93.1% | 92.6% / 93.4% | 590 / 78 / 49 |
| codebase-exploration | 137,961 | 99.7% / 99.7% | 16.0% / 12.7% | 99.6% / 99.6% | 100.0% / 99.9% | 540 / 3 / 0 |
| grep-output | 75,219 | 99.6% / 99.6% | 56.1% / 51.9% | 99.5% / 99.6% | 99.9% / 99.9% | 1005 / 3 / 0 |
| log-entries | 91,385 | 80.8% / 83.2% | 63.5% / 52.0% | 95.4% / 95.7% | 95.5% / 96.0% | 1180 / 237 / 46 |
| human-authored-json | 37,425 | 30.6% / 30.0% | 66.6% / 66.0% | 81.6% / 83.7% | 96.7% / 96.9% | 154 / 154 / 11 |
| issue-triage | 109,354 | 53.1% / 55.2% | 88.1% / 85.7% | 97.2% / 97.6% | 95.1% / 95.7% | 59 / 59 / 21 |
| rag-conversation | 171,913 | 0.0% / 0.1% | 84.6% / 83.2% | 99.1% / 99.4% | 100.0% / 100.0% | 42 / 42 / 0 |
| raw-build-log | 158,057 | 99.8% / 99.8% | 70.6% / 48.2% | 99.7% / 99.8% | 100.0% / 100.0% | 430 / 3 / 0 |
| relevance-probe | 49,157 | 64.1% / 71.0% | 82.4% / 77.2% | 97.1% / 97.8% | 95.8% / 96.6% | 225 / 225 / 13 |
| search-results | 96,647 | 95.0% / 95.4% | 74.3% / 59.4% | 96.5% / 96.5% | 96.6% / 96.6% | 505 / 62 / 34 |
| repeated-reads | 158,285 | 37.4% / 30.4% | 71.7% / 68.5% | 99.5% / 99.6% | 100.0% / 100.0% | 394 / 388 / 0 |
| sre-debugging | 312,276 | 88.4% / 89.9% | 67.4% / 62.4% | 98.5% / 98.7% | 97.1% / 97.5% | 3116 / 506 / 82 |
Recorded 2026-10-17 at b1231a8c, by the command in the
record's regenerate field, over Alternative A's own fixtures and harness. That arm runs
Alternative A itself, so CI does not re-derive it -- it checks these figures and
this provenance against the record instead.
Over the corpus the proxy removes 82.5% of the characters and 91.5% of
the tokens; their best configuration removes 51.5% and 61.4%. It is cheaper than
their best arm on 18 of 18 rows when nothing is ever fetched back, which is
the end of the range their markers are built for, and on 17 of 18 when every
moved block is fetched back. The block engine alone removes
72.0% and 55.9%: more of the characters than theirs, fewer of the tokens.
Where they still win, and why. On codebase-exploration, grep-output,
raw-build-log, sre-debugging and the four raw-data rows their best arm takes
83.2-99.8% off the tokens and the block engine 12.7-62.4%. Their number there is
a content-cache reference: the block is not made smaller, it is taken out of
the request, put in a store, and replaced by a <<ccr:hash,kind,size>> marker.
An engine with nowhere to put a block cannot match that, so on those rows the
ours column loses on reduction, and on cost when nothing is fetched back. The
proxy makes the same move: it is ahead of them on five of those eight rows, level
on grep-output and raw-build-log, and a tenth of a point behind on
codebase-exploration. The one row where the proxy costs more than they do is
agentic-conversation, and only when every block it moved is fetched back:
they move none of that conversation out, so they cost the same at either end,
while the proxy moves part of it and pays a retrieval for each part it wants
back.
The other column is a turn. A marker is not the content: to read what it
stands for, the agent spends a request. Of the 13,792 retention units planted in
the corpus, the block engine keeps 5,223 in the text and 8,569 more rebuildable
from the text alone, so every one of them is there with no extra turn; theirs
keeps 6,711 in the text and 7,075 behind its store, one retrieval call away.
0 are unrecoverable on our side and 6 on theirs. Their best arms force 17
round trips across the corpus to get their content back; the block engine
forces 0. The proxy, like theirs, trades a turn for every block it moves, and
that turn is what the fetch-rate end of the cost model prices.
What their marker costs is priced, not just its size. Their marker is only
redeemable because their proxy also sends a alternative_a_retrieve tool with the
request -- on by default (ccr_inject_tool), and on every later request once a
session has used it -- so every row where their best arm leaves a marker is
charged for that tool's definition as well, recorded from their own package by
bench/compression/alt-a/ccr-tool.py. The turn that first adds the tool also
rewrites the whole cached prefix behind it; that is not charged, which errs in
their favour. Ours needs no tool: our marker names a path the agent opens with
the Read it already has, and the path is priced at the length the proxy really
writes (<home>/.tok/<pid>/<15 digits>, src/compress/spill-path.ts) rather than
a shorter invented one.
browser-session is mostly the fixture. This payload holds four images, two
of them distinct, and the base64 in them is generated rather than photographic:
one distinct image alone folds from 160,032 characters to 5,572, which no real
PNG would do. What carries over to a real session is the duplication -- half the
image bytes are a second copy of an image already in the request, which is
44.3% of the whole payload. The run the marker names is still in the output
above it, so the reader rebuilds it without asking for anything, which is why
the characters fall much further than the tokens: the image tokens are counted
from pixels on both arms either way.
Reproduce the whole table:
python bench/compression/alt-a/run-theirs.py <alt-a-clone> <out-dir>
python bench/compression/alt-a/resolve-theirs.py <alt-a-clone> <out-dir>
node bench/compression/head-to-head.mjs <out-dir>
Against their published design
A second arm reimplements their published design from their own benchmark
generator's definitions — opaque hash markers, history compressed, a retrieval
tool and system message injected — so the four workloads with a published
comparator can be checked without their clone. node bench/compression/proof.mjs:
| workload | payload | theirs | ours | verdict |
|---|
| code-search | 17765 | 92.1% | 97.8% | ours |
| sre-debugging | 65694 | 92.2% | 98.6% | ours |
| issue-triage | 54174 | 72.8% | 97.5% | ours |
| codebase-exploration | 78502 | 47.4% | 54.7% | ours |
Four workloads, because those are the four this arm has a published comparator
for. The head-to-head harness scores eighteen; the other fourteen are not in
this arm, and are scored against their real implementation in the table above.