In a long Claude Code session, most of what gets sent to the API isn't your prompts. It's tool output: JSON from APIs, command logs, grep results, the same file read twice. And because the whole conversation is resent on every turn, that output is paid for again and again.
I built TokenTrimmer, a small local proxy that compresses tool output before it reaches the API, and spent most of the time measuring what actually works. Here's what I learned.
1. Synthetic benchmarks flatter compression tools
On synthetic payloads (big JSON arrays, repetitive logs), TokenTrimmer cuts 50% or more. On 9 of my own real Claude Code sessions (1,237 requests), the lossless mode saved 7.2% on the final request.
The gap is simple: synthetic tests are made of exactly the shapes a compressor is built for. Real sessions are mixed: plenty of prose, file reads and short outputs where there's nothing to squeeze. So the README leads with the real-session number, and compare/ lets anyone reproduce it on their own sessions.
2. Prompt caching changes the maths
With Anthropic's pricing, reading a cached prefix costs 10% of the normal input price, and writing the cache costs 125%. The cache matches on the exact bytes at the start of the request.
That means a compressor that edits earlier turns pays twice: every edit invalidates the cached prefix from that point on, and everything after it is billed again at the write price. In my replay, a mode from another tool that made each request 5.8% smaller ended up making the session 11% more expensive.
So TokenTrimmer has one hard rule: it only ever appends. A message's compressed form depends only on that message and the ones before it, and the same input always gives the same bytes. The prefix stays byte-identical from turn to turn, and cache hits continue. (It also matters for Claude's signed thinking blocks, which are rejected if earlier history changes.)
The lesson: judge compression by cache-weighted cost, not by how much smaller one request gets. Lossless mode came out 5.3% cheaper on that measure.
3. Verify every change, and fail open
Every encoding in the default mode has a decoder: JSON arrays of objects become compact tables, log lines sharing a pattern store it once, grep output is grouped by directory. Before each request is sent, a verifier decodes every rewritten tool result and checks it against the original. If anything doesn't match, the original request goes out unchanged.
To check that the model loses nothing, I asked Claude Opus 5.5 to recall exact lines of old tool output from the compressed conversations. Lossless mode scored 140/140, the same as the uncompressed original, plus 38/38 on questions whose answer sat behind a reference.
It also leaves alone what it shouldn't touch: system prompts, your messages, tool definitions, and results from file tools like Read and Edit, so edits still match the file exactly.
4. The biggest win wasn't clever encoding
Agents re-read the same lines constantly: the same file section, the same test output after a small change. Replacing lines the model already has with a short reference, such as:
[same as message 175 lines 16-19]
nearly doubled the savings compared with the encodings alone. It's about 12 tokens instead of the whole block, and it's still lossless: the verifier expands each reference against the request being sent.
Results
| Mode | Lossless | Final request | Cost with caching | Added latency |
|---|---|---|---|---|
| TokenTrimmer safe (default) | yes, every request verified | 7.2% smaller | 5.3% cheaper | ~9 ms |
| TokenTrimmer aggressive | no | 14.3% smaller | 11.6% cheaper | ~9 ms |
| TokenTrimmer stale10 | no | 29.8% smaller | 16.4% cheaper | ~9 ms |
The lossy modes are opt-in, and the README lists their measured accuracy cost.
It also works with Codex (tokentrimmer codex, with a ChatGPT login or an API key). Expect less there: on 78 of my Codex sessions the lossless mode saved 3.8% per request on average, because Codex already trims long command output.
Try it
npm install -g tokentrimmer
tokentrimmer claude
That starts the proxy in the background and runs Claude Code through it. tokentrimmer savings shows what it has saved, and a local dashboard shows the before and after text of every changed request. To measure without changing anything:
tokentrimmer --dry-run claude
Your number will differ from mine: sessions heavy on API responses and logs save more, sessions that are mostly file edits save less.
It's MIT-licensed, has zero dependencies, and runs entirely on your machine: https://github.com/an21an21/tokentrimmer
I'd love to hear what numbers you get, and any criticism of the measurement method.
Top comments (0)