headroom saves 34.5% on a tool result and 0% on the same bytes in a user message
Published
headroom-ai 0.41.0 compresses a JSON tool result by 34.54% and a 198 KB log by 96.01%. The same bytes as a user message save 0.00%: user messages are not compressed by default. With its own lossless guard on, the 96% row reverts to 0%.
headroom states its result as a compression ratio: "20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers". Its hero image prices a real run at 55,957 tokens down to 24,340 with the FATAL line surviving byte for byte. We priced it once already, on our own pipeline logs. That run went through the shipped router and through its log compressor (article 22).
That measurement left one question open, because it changed the payload in every row. This one holds the payload fixed. It changes only two controls an agent author has: which message role carries the bytes, and whether headroom is asked to verify its own losslessness.
We already own all four payloads. First, our own public API answer: 28,332 characters of JSON for 30 repositories. Second, 1,500 lines of this machine gateway log with three sentinel lines injected. Third, this repository README as prose. Fourth, a JSONL of 30 real X posts an agent collected today.
Everything ran in one local venv: uv venv plus uv pip install headroom-ai, no account, no proxy, no wrap. Library API only, one machine, one day.
The first run reproduced what the obvious call does. One user message, one compress, and the answer is 0.00%: the router labels it protected:user_message and returns the bytes untouched. That is the default, not a cold model: compress_user_messages ships as False.
1.The same bytes, moved into a tool result, save a third
| Payload we own | Role in the call | Tokens | Saved |
|---|---|---|---|
| Public API answer, 30 repositories | user, default config | 8,964 | 0.00% |
| Public API answer, 30 repositories | user, compress_user_messages | 8,964 | 34.76% |
| Public API answer, 30 repositories | tool result | 9,021 | 34.54% |
| Gateway log, 1,500 lines, 3 sentinels | tool result | 62,023 | 96.01% |
| Gateway log, 1,500 lines, 3 sentinels | user, compress_user_messages | 61,966 | 96.09% |
| README, 26,588 characters of prose | tool result | 9,053 | 0.00% |
| Agent tool output, 30 X posts as JSONL | tool result | 4,970 | 29.32% |
| Gateway log, verify_lossless=true | tool result | 62,023 | 0.00% |
JSON tool result
34.54%
Same bytes as a user message: 0.00%
Log tool result
96.01%
With its own lossless guard on: 0.00%
Prose tool result
0.00%
The router chooses noop for README-sized prose
Dashed line = top of the vendor stated JSON band
The JSON row is a real compression, not a truncation. All 30 repository full names survive. The long fields are replaced by retrieval handles: the compressed form carries four ccr: hashes and a field-type schema line. The string values are addressable rather than lost. That is headroom design working as documented.
The log row is the opposite trade. All three injected sentinels survive, but ERROR lines fall from 162 to 10. A log question that needs one of the other 152 error lines cannot be answered from what the model was given. Article 22 measured the same shape on a different payload and got 4 of 10 answers right after compression, so this is the same finding from a second payload.
2.Its own lossless guard reverts the best row
headroom ships CompressConfig.verify_lossless. Turn it on for the row that saves 96.01% and the run returns the input unchanged: 62,023 tokens in, 62,023 out, 0.00% saved, one reverted message. The tool verifies its own output, decides the compression is not lossless, and gives the bytes back.
Read that as the product making a statement about itself. The 96% row is recoverable-only compression, which is why it also ships a retrieval tool. The savings and the retrieval tool are one feature, not two.
Careful with the 0.00% rows in this table: they mean the router chose to leave the bytes alone, not that headroom failed. This measurement changes no proxy, no MCP (Model Context Protocol) server and no wrap install, so the rows describe the library path an agent author calls directly.
What we could not measure
- The proxy, wrap and MCP paths. Every row here is headroom.compress() in a local venv. Nothing in this table says how the proxy behaves on the same bytes.
- The ONNX branch. The first call prints "Native content detection requires ONNX Runtime 1.24+; using pure-Python detection for this process". The classifier that picked these routes is therefore the fallback one.
- Answer quality, beyond the fact counts above. We counted surviving full names and sentinels, not whether a downstream model answers well from the compressed text.
- The tokenizer. Every count is headroom’s own counter, so the ratios are internally consistent but are not tiktoken numbers.
- n = 4 payloads on one machine on one day. The prose row is one file, and the log row is one 1,500-line tail.
Decision
- Put compressible bytes in tool results
- The role decides the ratio before any compressor runs: identical bytes saved 34.54% as a tool result and 0.00% as a user message.
- Agent authors already deliver API answers and logs as tool results, so this costs nothing
- If your pipeline uses user messages, set compress_user_messages true and measure again
- Do not compress incident logs without the retrieval side
- 96.01% saved and 152 of 162 ERROR lines gone: the trade is retrieval, not deletion.
- Article 22 measured 4 of 10 log questions answered correctly after compression
- JSON tool payloads are the safer target: 30 of 30 identifiers survived with 4 ccr handles
- Read verify_lossless as the vendor honest guard
- It converts a 96.01% headline into 0.00% on the same bytes, which is what a guard should do.
- Use it while adopting, then decide per payload class whether retrieval is wired
- What would change this
- Measuring the proxy and MCP paths, or a payload where a downstream model has to answer questions after compression.
Machine and scope: MacBook Pro M1, 8 GiB, macOS 26.3, headroom-ai 0.41.0, 2026-10-16, four payloads, library API only. Raw rows: docs/analysis/2026-10-16-headroom-tool-message-position.jsonl (13 rows). Scripts: ~/Projects/headroom-probe/emit_evidence.py, matrix.py, facts2.py.