← All posts
Claude Code Token Optimization Knowledge Graph Local AI Field Notes

The Token Diet

A year of building with Claude Code left me with over 50 GB of repos, a wiki, and hundreds of memory files. The model kept re-reading all of it, every session. So I stopped feeding it files and started feeding it an index. Per-turn cost dropped by more than half, and I have the dashboard data to show exactly where it went.

By Robert Graham August 2026 10 min read
Diagram of a local knowledge base shared by Claude Code and Codex: both connect over MCP to an mcp_server.py tool wrapper, which calls a FastAPI backend exposing health, status, search, ask, and index endpoints, backed by a Qdrant vector store indexing documents, repositories, wiki, scripts, and memory files.

00 The chart that made me stop

I have been building a lot with Claude Code, not just agentic ai projects but personal projects, mobile apps, games, enterprise style monitoring and dashboards for all my infrastructure etc. A year of that produced 55 repositories, over 50 GB on disk, a curated wiki, and 381 memory files the agent wrote for itself along the way. It also produced a token usage I was reading the way most people read a utility statement: glance, wince, move on.

Then I built a small local dashboard that parses Claude Code's own transcript files and charts where the tokens go, along with gemini and some plugin monitoring. One number stopped me. On August 16, raw input tokens were 0.019 percent of everything the model saw that day. Nearly forty thousand input tokens against 212 million cache reads. The prompt I type is a rounding error. The cost lives in what the session forces the model to read.

And what was it reading? My own work. Again. Every session started with the agent grepping through repositories it had already explored hundreds of times, re-deriving architecture it had itself written, and re-reading files wholesale to answer questions it had already answered in April. I was paying, per turn, for the model's amnesia about a corpus I had spent a year helping it create.

The prompt is a rounding error. The bill is context. And most of my context was a year of my own answers, re-read from scratch.

01 The week the price tripled

Through July the pattern was tolerable because I mostly lived inside one repository at a time. My dashboard says those days averaged around six thousand paid tokens per turn. Fine. Cache does its job when you stay in one place.

The first week of August broke that. I was doing portfolio-wide work: tracing one identity pattern across a dozen repos, comparing decisions I had made months apart, pulling threads that crossed project boundaries. The per-turn price responded immediately. August 2 through 5 averaged 15,289 paid tokens per turn, with one day peaking above 24,000. Same model, only me, triple the price, because every cross-repo question turned into a fresh archaeology dig through raw files.

That was the moment the obvious thing finally became obvious. I did not have a context problem. I had a retrieval problem. The knowledge existed, in code, in docs, in the agent's own memory files. It was just stored in the most expensive possible format for a language model to consult: loose, unindexed text that has to be re-read in full to be useful.

So on August 8 I spent one deliberately heavy day fixing that. It is the tallest bar on the chart below, 30.9 million paid tokens, and it was the day Claude and I indexed the year.

10M20M30M 2026-07-17: 11.3M paid tokens, 1713 turns2026-07-18: 4.3M paid tokens, 650 turns2026-07-19: 6.1M paid tokens, 931 turns2026-07-20: 7.2M paid tokens, 694 turns2026-07-21: 16.6M paid tokens, 3553 turns2026-07-22: 13.2M paid tokens, 2682 turns2026-07-23: 0.0M paid tokens, 3 turns2026-07-24: 3.8M paid tokens, 605 turns2026-07-25: 2.0M paid tokens, 477 turns2026-07-26: 1.5M paid tokens, 271 turns2026-07-27: 5.8M paid tokens, 1178 turns2026-07-28: 12.7M paid tokens, 2321 turns2026-07-29: 1.5M paid tokens, 282 turns2026-07-30: 13.2M paid tokens, 2866 turns2026-07-31: 12.4M paid tokens, 2045 turns2026-08-01: 4.6M paid tokens, 576 turns2026-08-02: 1.5M paid tokens, 78 turns2026-08-03: 6.8M paid tokens, 521 turns2026-08-04: 6.0M paid tokens, 249 turns2026-08-05: 14.8M paid tokens, 1057 turns2026-08-06: 16.2M paid tokens, 2779 turns2026-08-07: 19.3M paid tokens, 3839 turns2026-08-08: 30.9M paid tokens, 4592 turns2026-08-09: 10.8M paid tokens, 1961 turns2026-08-10: 10.7M paid tokens, 1723 turns2026-08-11: 8.1M paid tokens, 875 turns2026-08-12: 4.6M paid tokens, 552 turns2026-08-13: 11.8M paid tokens, 1495 turns2026-08-14: 9.0M paid tokens, 1710 turns2026-08-15: 3.2M paid tokens, 284 turns2026-08-16: 10.1M paid tokens, 1631 turns 07-1707-2407-3108-0808-16
before the index Aug 8: index build day after the index
DAILY PAID TOKENS (INPUT + OUTPUT + CACHE WRITES), JUL 17 TO AUG 16. SOURCE: MY LOCAL TOKEN DASHBOARD, PARSED FROM CLAUDE CODE TRANSCRIPTS.

Everything to the right of the purple bar is portfolio-wide work, the same kind that cost 15,000 tokens a turn in early August. It now runs at 6,677 per turn averaged across the eight days that followed, while turn volume went up five-fold. Cross-repo questions started costing what single-repo questions used to cost.

02 Four layers, four kinds of waste

No single tool did this. Four layers went in, and each one kills a different way that tokens were being wasted. They barely overlap.

A question from a Claude Code turn Code graph who calls this, blast radius, test coverage 3,213 nodes 29,425 edges Knowledge base what did I decide, where is it written down 2,904 files 35,279 chunks RTK every shell command, output compressed 10,620 cmds 76.6% cut Memory files lessons that survive the session 361 files Small, precise context instead of raw file dumps
WHERE A QUESTION GOES NOW. EACH LAYER RETURNS AN ANSWER MEASURED IN HUNDREDS OF TOKENS, NOT A FILE MEASURED IN THOUSANDS.

RTK: stop paying retail for shell output

RTK is a Rust CLI proxy that sits between Claude Code and the shell. A hook rewrites git status to rtk git status, and RTK returns a compressed, structured version of the output instead of the raw dump. The agent still gets everything it needs to act. It just stops receiving eighty lines of decoration around four lines of signal.

My totals since installing it: 10,620 commands proxied, 5.6 million tokens saved, 76.6 percent average compression. The single biggest line item is file reads at 4.3 million tokens saved. Nobody thinks of cat as a cost center. It is the whole grocery bill.

The code graph: structure questions without file dumps

code-review-graph parses the codebase with Tree-sitter into a persistent graph, kept current by hooks on every file change. This repo's graph is 3,213 nodes and 29,425 edges across 642 files. When the agent needs to know who calls a function, what a change would break, or whether something has test coverage, it queries the graph and gets a structural answer in a few hundred tokens. The old way was a Grep cascade followed by reading five files end to end, thousands of tokens to reconstruct a fact the graph simply knows. My project instructions now open with a rule: graph first, files only when the graph cannot answer.

Code structure is only half the graph story. A second tool, graphify, builds a knowledge graph over the whole portfolio, not just the code: concepts, documents, and components, linked across repo boundaries. This is what it looks like. Every dot is a node, every color is a detected community, and the bright hubs are the pieces the rest of the year leans on.

A circular force-directed knowledge graph on a dark background: thousands of colored nodes in clusters, dense bright hubs where many edges converge, and a halo of small satellite clusters around the edge.
THE PORTFOLIO AS A GRAPH: 5,035 NODES, 5,695 EDGES, 637 DETECTED COMMUNITIES ACROSS 690 FILES AND ROUGHLY A MILLION WORDS.

The stat I like most about this map is what it cost to draw: nothing. Its report shows 99 percent of the graph was extracted structurally, by parsing, with zero model tokens spent on inference. The most token-expensive thing I own to read was free to index. That asymmetry, expensive to re-read but nearly free to map, is the entire reason this stack works.

The knowledge base: a year of answers, indexed

This is the layer that changed cross-repo work. A local FastAPI service holds a Qdrant vector index over three roots: the curated wiki, every markdown file across all 55 repositories, and the agent's own memory files. Embeddings come from nomic-embed-text running under Ollama on the same machine. Nothing leaves the box. As of this writing the index holds 2,904 files in 35,279 chunks, and it reindexes itself daily, incrementally, touching only what changed.

Claude reaches it through an MCP tool. Ask a question that touches history, "how did I wire the token exchange policy in the banking demo," and instead of an expedition through repositories, the agent runs one kb_search call and gets ranked excerpts with citations back to the source files. It reads eight results, not eight repos, then opens only the one file that matters.

Because the index build was itself a project, I instrumented it. The numbers from the validation run are the part of this story that surprised me most, so here they are, measured on the laptop that ran it:

12.5 min
full rebuild: 2,836 files chunked and embedded into 34,165 vectors, zero failures
2.11 s
incremental reindex after one file changed; the other 2,836 were verified and skipped
3.15 s
to scan the entire corpus and confirm nothing changed
383 MB
total index on disk, against a 44 GB corpus: under one percent
400 → 8
candidates per search: 200 semantic plus 200 keyword, fused and re-ranked to eight cited excerpts

Read those incremental numbers again, because they carry the whole economic argument. A full rebuild costs twelve and a half minutes, once. After that, keeping a year of work searchable costs about two seconds per change. The daily reindex usually finds a handful of edited files, re-embeds only those, and is done before the coffee order. Retrieval is the same shape: every search sifts all 34,000 chunks, fuses the semantic and keyword rankings, and hands back eight excerpts in about a second. The expensive thing happens once. The cheap thing happens forever.

The instrumented run also caught things I did not ask it to find. It flagged 1,012 duplicate files sitting in 157 groups across the corpus, a year of copy-paste debt I had never noticed, and it confirmed 70 separate CLAUDE.md instruction files are part of what gets indexed, which means the agent's own operating rules are retrievable the same way its work is.

Memory: lessons that stop being re-learned

The quietest layer. Claude Code writes memory files as it works: what broke, what the fix was, which approach I rejected and why. There are 381 of them now, and they are indexed by the knowledge base like everything else. A lesson learned in March costs a few hundred tokens to recall in August. Without the index, recalling it meant either re-reading the history or, worse, re-living it.

03 What the numbers did

5.6M
tokens saved by RTK, measured across 10,620 commands
76.6%
average compression on shell output
56%
drop in paid tokens per turn, pre-index week vs the eight days after
0.019%
of what the model saw on Aug 16 was raw input; the rest rode cache
8M
projected 30-day token savings at the current run rate

Two of these deserve a closer look, because they are the ones I would have gotten wrong by intuition.

First, the 56 percent. The honest comparison is not July versus August. July was cheap because I stayed inside single repos, and any measurement that ignores that is flattering itself. The fair comparison is early-August portfolio work without the index, 15,289 paid tokens per turn, against the same kind of work after it, 6,677. Same breadth of questions. Less than half the price. And I did five times as many turns in the after window, so the total did not just hold, it held under load.

Second, the 0.019 percent. My daily cache reads run in the hundreds of millions of tokens, and on the dashboard that green chart towers over everything else. That used to look alarming. It is the opposite. Cache reads cost roughly a tenth of fresh input, so a tall green bar means the expensive context was written once and re-used all day. The number to watch is cache writes, the orange bars, because that is what you pay full price to create. The whole strategy reduces to one sentence: write less context, read it more often.

The one-day tax

Building the index was the most expensive single day on my chart: 30.9 million paid tokens, 4,592 turns, nearly all of it Claude reading a year of material to curate the wiki and decide what mattered. The mechanical half costs no tokens at all: chunking and embedding the corpus is 12.5 minutes of local compute. That day paid for itself within the week. If you try this, expect the spike, budget for it, and do it once, deliberately, rather than letting the same reading happen dilutely forever.

04 Why local infrastructure is the right shape for this

Everything in this stack runs on my own hardware. The embeddings model, the vector store, the graph, the compression proxy, the dashboard that measured all of it. That was not a privacy reflex. It follows from what this data is.

The corpus is my working life: every repo, every decision record, every memory file the agent wrote about my mistakes. It changes hundreds of times a day, which means indexing has to be cheap enough to run constantly and close enough to watch the filesystem. And the queries against it happen mid-turn, inside an agent loop, where a 40 millisecond local call and a 400 millisecond remote call are the difference between a tool the model reaches for by habit and a tool it avoids.

There is also a quieter reason. Retrieval only earns trust if you can see it. My dashboard reads the transcripts, the search service reports exactly which files back every answer, and when a result looks stale I can watch the reindex fix it. A local system lets me audit the loop end to end. I would not have found the 0.019 percent number, or the per-turn regression that started all this, inside someone else's billing page.

05 If you start today

A year of accumulated work made my version of this dramatic, but none of the layers require a year of material. Order matters, though. This is the sequence I would run with hindsight:

The framing I keep coming back to: a year ago I thought the output of all this work was the demos and the repos. The output was actually a corpus that knows how I build things. The moment I started treating that corpus as infrastructure, with an index, a graph, and a meter, the same agent got cheaper, faster, and noticeably less repetitive. The model did not get smarter in August. Its library got a card catalog.

The model did not get smarter. Its library got a card catalog.


Also in this series
Sandboxing the Agent: NVIDIA OpenShell, IBM Verify, and Shared Signals
blog.iamidentity.ai/blog/sandboxing-the-agent
The security half of running agents on your own terms: reachability from the sandbox, everything else from identity, with the failures included.
And the dashboard thread
So You Have a Dashboard
blog.iamidentity.ai/blog/so-you-have-a-dashboard
Field notes on what dashboards are for and what they hide. This post is what happened when I pointed one at my own token spend.