ES

Headroom compresses what your AI agent reads, before it reaches the model

Leo G.8 minLeer en español

Perforated metal sheet, close up, with the light shifting from one side to the other.
Perforated metal sheet, close up, with the light shifting from one side to the other.

You ask Claude Code to look into why an endpoint is failing. It runs the tests, and one of them hands back a ten-thousand-line log dump. That whole log — with its three thousand repeated “connection OK” lines and a single FATAL line in the middle — goes into the model’s context. You only needed that one line, but you paid for all ten thousand.

Headroom (opens in a new tab) is a free, open-source tool that compresses that before it reaches the model: tool outputs, logs, search results, files, conversation history. It runs on your machine — it doesn’t send your code to any server to compress it — and the central promise is that: the same answer, for a fraction of the tokens.

How it works

It doesn’t rewrite the text with another language model or summarize with generative AI, which is the first thing you’d picture and would be slow and unreliable. Every content type gets its own compressor, chosen by rules:

A piece of data's path to the model, through Headroom Your agent Claude Code, Cursor… CacheAligner protects the cache ContentRouter picks the compressor CCR keeps the original The model Anthropic, OpenAI… one compressor per content type SmartCrusher JSON CodeCompressor code Kompress-v2-base text
ContentRouter looks at what each piece of data is and routes it to a specific compressor. CCR keeps the original before compressing, so it can be handed back if the model needs it.
  • SmartCrusher compresses JSON — arrays and nested objects — with statistics, not a keyword list: it looks at each field’s variance and keeps the outliers, the error items, and the first and last of each list. If you have a hundred search results and ninety-five of them are nearly identical, it keeps the ones that matter and summarizes the rest.
  • CodeCompressor understands code syntax — Python, JavaScript, TypeScript, Go, Rust, Java, C/C++, Perl — and keeps imports, function signatures, and types, which is the part a model needs to understand what a file does without reading the whole thing.
  • Kompress-v2-base is a purpose-built model, published on HuggingFace (opens in a new tab) and trained specifically on agentic traces, for text that’s neither JSON nor code: prose, search results, documentation.

CacheAligner doesn’t compress anything: it flags which parts of the text are volatile — they change on every request — so they don’t break the prefix caching your provider already uses. Model providers charge much less for tokens they’ve already seen before in the same spot; if something that changes constantly sits at the start of the prompt, that discount is lost on every call.

The numbers, with the exact command that produced them

Headroom publishes four scenarios built from real MCP tool output formats, measured with the provider’s own tokenizer. They’re reproducible with the same seed, and you get the same numbers:

uv run python benchmarks/index_proof_table.py --seed 20260902
Scenario Before After Saved
Code search (100 results) 17,199 13,597 21%
Incident debugging 55,957 24,340 57%
Codebase exploration 58,801 33,895 42%
GitHub issue triage 46,067 32,429 30%

The savings depend on how repetitive the content is: a JSON array with the same shape in every element, or a log with the same line a thousand times over, clears 90% in the authors’ own tests. Text that’s already dense — a short answer, no padding — compresses little or not at all. Compression itself costs under a millisecond: 0.21 ms on 10,000 tokens, 1.4 ms on 100,000, so it doesn’t show up in the latency of a normal conversation.

Compressed, but never lost

The part that makes this safe to use is that nothing gets discarded. The name is CCR — Compress-Cache-Retrieve: compress, store in a cache, be able to retrieve. The original of every piece of data that gets compressed stays saved on your machine, and if the model needs the exact detail that got summarized, it has a tool — headroom_retrieve — to ask for it back.

It’s the same underlying idea we already use on this blog for article comments: nothing gets deleted, it’s stored and can be asked for again when it’s needed. Here the one “asking for it back” isn’t you, it’s the model itself, when the compressed answer isn’t enough for it to answer well.

Does it change what the model answers?

That’s the obvious question, and Headroom answers it with an accuracy table, not just a sentence:

Benchmark What it measures Uncompressed With Headroom Delta
GSM8K Math 0.870 0.870 ±0.000
TruthfulQA Factual accuracy 0.530 0.560 +0.030
SQuAD v2 Question answering — 97% at 19% compression
BFCL Tool use — 97% at 32% compression

At a hundred test cases, a delta of ±0.03 falls within normal margin of error: it doesn’t mean TruthfulQA improved, it means there’s no detectable difference. The real result is the same with and without compression, across all four benchmarks.

How to try it

It installs as a Python or Node package, and it’s used three different ways depending on how much of your project you want to touch:

# install
pip install "headroom-ai[all]"        # Python, ships the CLI
npm install headroom-ai               # TypeScript, library only

# the simplest option: wrap the agent you already use
headroom wrap claude                  # also: codex, cursor, aider, opencode…

# without installing anything in your project: run it as a proxy
headroom proxy --port 8787            # any OpenAI/Anthropic-compatible client

# or inside your own code
from headroom import compress
from openai import OpenAI

messages = [{"role": "user", "content": "Analyze these results"}]
result = compress(messages, model="gpt-4o")
response = OpenAI().chat.completions.create(model="gpt-4o", messages=result.messages)
print(f"Saved {result.tokens_saved} tokens ({result.compression_ratio:.0%})")

headroom wrap is the option for anyone who just wants the savings without changing any code: it starts a local proxy, configures the agent to route through it, and headroom unwrap claude undoes all of it. There’s also an MCP server (headroom_compress, headroom_retrieve, headroom_stats) for anyone already using that protocol.

A privacy detail worth clearing up

Headroom’s own documentation has, in two different places, two claims that contradict each other about whether it sends data anywhere by default. Since that matters, I went to the source code instead of taking the docs at their word:

There are two separate switches, and it’s easy to mix them up:

  • HEADROOM_TELEMETRY — stats kept only on your machine, so the headroom stats command has something to show. Off by default.
  • HEADROOM_BEACON — an anonymous session summary (never the content of your prompts, or your code) that does get uploaded to Headroom Labs’ servers. On by default: you have to turn it off on purpose.

It’s disabled with HEADROOM_BEACON=off, with the standard DO_NOT_TRACK=1 convention, or by running in --offline mode. If it matters to you that nothing leaves your machine — which is Headroom’s whole reason for existing, really — it’s worth turning off before the first time you run it.

When it’s worth it and when it isn’t

It’s worth it if you run a coding agent daily and want to save tokens without touching your project, if you work across more than one agent (Claude Code and Codex, say) and want them to share memory, or if being able to retrieve the original of what got compressed matters to you.

It doesn’t add much if you already use one provider’s native compaction and don’t need anything more, or if you work in an environment where you can’t run a local process — a restricted sandbox, say. It also doesn’t help much in short conversations or with text that’s already dense: there’s nothing repetitive there to compress.

It’s free software, under the Apache 2.0 license, and the repository itself was “Repository of the Day” (opens in a new tab) on Trendshift — a sign this isn’t a niche project, but something plenty of people are already using.

Comments