
Sonar published a trace of 18 pull requests written by a coding agent against its own codebase on 1 September. One of them, a backend change of roughly 800 lines, was billed 156 million tokens and produced 289,000 tokens of output. The agent was billed for more than 500 times what it wrote.
Almost none of that was new reading. 152.8 million of those tokens were cache reads, because the entire conversation goes back to the model on every turn. The agent did not read the codebase 512 times. It read it once and paid for it 512 times.
Which means a token's cost is set by when it entered the context, not by what it was. The same file costs two orders of magnitude more at turn 40 than at turn 500, and no billing dashboard breaks it out that way.
The arithmetic behind the invoice
The full instrumented trace for that one PR reads like this. 512 model round-trips. 106,000 tokens of fresh input. 3.1 million tokens of cache writes. 152.8 million tokens of cache reads. 289,000 tokens of output. Context window peaking at 458,700 tokens. About $41 for the session.
Across all 18 PRs the shape holds. Roughly 234 million context tokens per PR, around 700 round-trips, context windows routinely peaking between 450,000 and 975,000 tokens. Mean cost around $65 per PR, median around $52.
The mechanism is not exotic and it is not a bug. An agent loop is stateless underneath. Every step re-sends the whole transcript, because that is the only way the model knows what happened. Prompt caching drops the per-unit price of those repeated tokens to roughly 10% of the input rate, which is the reason the bill is $41 and not $400.
So caching works. It just changes the multiplier, not the shape. It turns a 470x problem into a 47x problem, and 47x still compounds on every mistake made early.
The research engineer who wrote it up, Antonio Aversa, titled it around the part that stings: the agent reads the same 600 lines 400 times.
The read that keeps charging
The clearest example in the trace is small enough to be embarrassing.
Around turn 42 of that 512-turn session, the agent needed one function. It read the whole file. 618 lines, 6,472 tokens, to get at roughly 67 lines and 700 tokens of actual signal. Call it 5,770 tokens of waste.
If that were the end of it, nobody would write a blog post. It cost a fraction of a cent and it saved a round-trip. But those 5,770 tokens then sat in the transcript for the remaining 470 turns and got re-billed on every one of them. 5,770 times 470 is about 2.7 million tokens, which Sonar puts at roughly $0.54, for one file read that a more precise tool would have made 9 times smaller.
Fifty-four cents is nothing. Fifty-four cents multiplied by every sloppy read in a 700-turn session, across every agent on the team, every day, is the $65 PR.
The thing worth internalising is the shape of the curve, not the dollar figure. Waste introduced at turn 42 is amortised over 470 turns of re-billing. Waste introduced at turn 500 is amortised over 12. The identical mistake differs in price by roughly 40x depending only on when the agent made it.
That inverts the intuition most people are running on. The default mental model is that a long agent session gets expensive because it does a lot of work. The trace says a long agent session gets expensive because of what it picked up in the first ten minutes and never put down.
Grep is a text tool answering a graph question
The reason agents over-read is that the tool they reach for cannot answer the question they are actually asking.
"Which method does this call bind to" is a graph traversal. "What does this return" is one edge. "Who calls this" is a reverse edge lookup. An agent with grep and read approximates all three by pulling in whole files and letting the model sort it out, which is a reasonable strategy when the model is the only thing in the loop that understands types.
Sonar's answer is a semantic index. SemSitter, their navigation engine, keeps a Unified Dependency Graph of the repo updated on every change. Functions, methods, classes, fields and parameters are nodes. Calls, references, returns, has-param, is-type, contains and extends are typed edges, plus documented_by edges linking code to the relevant documentation. The agent asks for a node and gets that node plus its relationships, instead of asking for a filename and getting 618 lines.
It ships through the SonarQube CLI and the SonarQube MCP Server, and covers Java, Python, JavaScript and TypeScript, C# and Rust.
Read the vendor benchmark like a vendor benchmark
Sonar's marketing number for Vortex is up to 36% fewer tokens and 92% fewer issues. The 36% is real and it is also the best result in the set.
Their June study ran ten trials per configuration on Opus 4.8, gated so that only runs that compiled and passed the targeted tests counted. Across six tasks the mean token reduction ranged from 36% on a Java self-typing change down to 5% on a TypeScript mutation context change. Input tokens fell between 11% and 31%, output between 4% and 35%.
So the honest read is a mid-teens to low-twenties percentage saving on a typical task, with a good day at 36% and a bad day at nothing much. That is still a real number for a drop-in index, and it is not the 36% on the slide.
The measurement work is more valuable than the product claim anyway, and you do not need to buy anything to use it.
What this changes on Monday
Start by separating fresh input from cache reads. Most teams watch total spend and some watch tokens per PR, and most dashboards report those two token classes as one number. The ratio between them is the whole story. If cache reads are 95% or more of your context tokens, you are not paying for research, you are paying rent on a decision the agent made early.
Then treat context hygiene as a scheduling problem rather than a volume problem. In that 512-turn trace, pruning 10,000 tokens at turn 40 was worth about forty times pruning the same 10,000 tokens at turn 500. Compaction that fires on a window-full threshold is firing at exactly the wrong end of the session. The expensive tokens are already amortised by then.
Front-load precision instead. Anything that makes the agent's first twenty reads narrower pays back across the entire run, whether that is a semantic index, a decent set of project instructions, or just pointing it at the right three files yourself. Anything that makes the last twenty reads narrower barely registers.
And take the 0.19% seriously as a design signal. An agent billed for 500 times what it produces is not inefficient at writing code. It is efficient at writing code and catastrophically imprecise at deciding what to look at, and those are separate problems with separate fixes. Everyone is buying better models. The trace says the leverage is in the retrieval step, which is the cheap part of the stack and the part you actually control.