headroom vs codegraph: compress or navigate?

One squeezes the conversation before every API call, the other stops the agent needing to read so much in the first place. Only one of those strategies survives a long session.

Profile photo of Paul Irolla

By Paul Irolla

Founder · AI & developer tools · Tokenade

Ph.D. in AI · builds token-optimization tooling for AI coding agents

View author page
6 min read
Cite this page
Part of the reduce Claude Code token usage pillar. This page is the head-to-head between the two most-discussed strategies in the category, and they do not measure alike.

Is headroom or codegraph better?

codegraph, on the evidence available — but the interesting part is why compression loses to navigation here. codegraph publishes −35% cost and −71% tool calls across seven repositories, and finishes at roughly break-even on my long-session benchmark. headroom finishes 53% more expensive than running no tool at all, last of the twelve tools tested. That is a striking result for a well-engineered project with a large following, so it deserves a mechanism rather than a scoreboard. I run the open benchmark and I sell a competing tool. Check the reasoning against your own sessions rather than taking the ranking on trust.

What does headroom actually do?

It compresses the entire message array before every API call. Python SDK plus CLI proxy plus MCP server, Apache 2.0, roughly 18.7k stars. The pipeline runs in three stages: CacheAligner stabilises the static prompt prefix by moving timestamps and UUIDs to a non-cached tail, ContentRouter sends each piece of content to a format-specific compressor via an ML content detector — JSON, code, text, logs, diffs, HTML — and IntelligentContext scores what is left on six relevance dimensions. It is reversible, which matters: originals stay in a local LRU cache and the model gets an injected headroom_retrieve tool to pull one back, with optional BM25 sub-search. The per-workload numbers are strong — 92% on code-search results and SRE incident logs, 73% on issue triage. So why does the session cost go up? Because it rewrites the window on every call, and the window is what providers cache. Prompt caching only pays when the prefix is byte-identical between turns. When compression decisions change between turns — and they do, because the content changes — the prefix changes, the cache misses, and you re-pay full price for context you had already bought. CacheAligner exists precisely to fight this, which tells you the project understands the risk. On a long agent loop it is not enough. There is a second cost. When the compressed version is not enough, the model calls headroom_retrieve and pulls the original back in — so you have paid for the compressed copy and the original, plus the round-trip. On a short task that is rare. Over a long session it compounds. The footprint is heavy too: Python 3.10+, a 150M-parameter ModernBERT model, Magika for content detection, and 16 to 50 ms of overhead per call.

What does codegraph actually do?

It removes the need to read, rather than shrinking what was read. tree-sitter parses your source into an FTS5 SQLite knowledge graph, served over MCP: impact analysis, call graphs, symbol lookup, across 20-plus languages and 14 frameworks. The agent asks where a function is used instead of opening four files to find out. Practical strengths:
  • A bundled Node.js runtime. No version management, cross-platform, and an interactive installer that detects eight agents and writes the MCP config itself.
  • Framework-aware routing across fourteen frameworks, including uncommon ones like Drupal and Vapor.
  • A debounced file watcher with staleness banners, so the agent knows when its index is behind the working tree instead of answering confidently from stale data.
Its published −71% tool calls is the more trustworthy half of its benchmark. Fewer tool calls follows mechanically from having an index and you can verify it in one session. The −35% cost figure is downstream of that and shows real run-to-run variance — a four-run spread on Tokio, by codegraph's own reporting. What it does not do: no output filtering, so verbose shell output still arrives at full size; FTS5 keyword search only, no semantic retrieval; no deferral of MCP manifests; no structural compression of the files the agent does open.

Compression versus navigation: which generalises?

Navigation, because it does not fight the provider's cache. That is the whole difference in one line. An index changes what the agent asks for. A window compressor changes what the provider sees, and the provider has an economic model built on that text staying stable. Any tool that rewrites the prefix is spending cache hits to buy token count, and cached input is billed at a fraction of fresh input on every major provider. Trading the first for the second is a bad exchange rate. It also explains why headroom's per-workload numbers can be honest and its session result still bad. 92% off a code-search result is real. It is measured on one payload, in isolation, without the cache invalidation that same rewrite causes on the next turn. None of that makes window compression a dead end. It makes it a strategy whose payoff depends entirely on stability between turns — which is a much easier condition to meet in a batch pipeline than in an interactive agent loop.

What do both of them miss?

  • Command output. codegraph does not touch it. headroom compresses it inside the window, but only after it has already been produced and paid for once at the tool boundary.
  • Whole-file reads for editing. An index says which file; it does not shrink it. A compressor shrinks it and risks the cache.
  • MCP manifests. Every connected server ships tool definitions before your first message, used or not. Neither tool defers them.
  • Re-reads. The same file entering context four times costs four times. An index lowers the odds; neither deduplicates.

Which one should you pick?

Pick codegraph if you want the safer bet and the easier install. It is the one with a published number, a low-friction installer, and a failure mode — a stale index — that announces itself. Pick headroom if your workload is batch rather than interactive: long, stable payloads processed once, where cache alignment is not being invalidated every turn, and where 92% off a large JSON blob is the whole story. That is a real use case; it is just not an agent coding loop. Pick neither if most of your spend is command output. Neither tool is positioned on that channel in a way that survives a session.

How to apply this today

  1. Look at your cache-hit rate before installing anything that rewrites the window. If it is high, a compressor is spending your best asset.
  2. Count tool calls for one session. It is the metric an index moves, and the one you can verify yourself.
  3. Split spend by channel — shell output, file reads, conversation history — before attributing a result to a tool.
  4. Re-measure after a week, not after a task. Both of these look different at those two scales, and the week is the one you pay for.

What goes wrong (anti-patterns)

Reading a per-payload compression rate as a session saving. 92% on one blob and 53% more expensive over a session are both true of headroom, and they are not in contradiction. Ignoring prompt caching. It is the largest single lever on modern pricing, and it is the one a window rewriter quietly spends. Treating −35% as a guarantee. Vendor-published median over seven repositories, with visible variance. Good faith, still a sample. Stacking a compressor on top of an index. The index reduces what enters the window; the compressor then destabilises the prefix that the index just made small. You get the downside of both.
See also:

Ranked #1 on the Token-Harness Optimizer Leaderboard.

Tokenade ranks #1 in the Token-Harness Optimizer Leaderboard — an end-to-end benchmark of agent token optimizers measured on real coding sessions. Set it up once, it works on every prompt. Works with Claude Code, Cursor, Codex, Copilot & more.