Messy code costs more AI tokens for the same reason it has always cost people more time. Before anyone can change code, they have to read enough of it to understand it, and tangled code takes more reading. A coding agent does that reading in tokens, the chunks of text a model reads and is billed by.
I’ve been building software for 30 years. I hold that much as settled. How big the effect is remains open. The best controlled study so far, from Sonar, found agents used 7 to 8% fewer tokens on cleaner code and solved about the same share of tasks. On one kind of task the cleaned-up code cost slightly more. That result says something useful about how to split code.
Where LLM token cost comes from in a coding agent
A chat assistant answers one request at a time. A coding agent works in a loop. It reads files, runs commands, edits code and reads the results, and each of those steps sends another request to the model. Longju Bai and colleagues measured what that does to a bill in How Do AI Agents Spend Your Money? (2026). Agentic coding tasks used about 1,000 times the tokens of code reasoning or code chat, and input tokens drove the cost more than output did.
Most of that input comes from the conversation so far. Anthropic’s Manage costs effectively (2026) says Claude Code sends the whole conversation with every request. Each batch of tool results goes back in a request of its own. So a file the agent opens early in a session stays in its context, the text sent to the model with each request, for every step after that. Pengfei Gao and Chao Peng’s More with Less (2025) names token counts that grow quadratically with each turn as one reason agent costs are hard to predict.
Prompt caching makes the repeats cheaper. Anthropic’s Prompt caching docs (2026) price a read from the cache at a tenth of the normal input price, or a twentieth on Opus 5.5 and Sonnet 5.5. Writing new content into the cache costs more than normal input, from 1.25 times upwards. So the history is cheap to resend, and each new file the agent opens, or opens again after changing it, is paid for at the higher rate.
Why messy code uses more tokens
By messy I mean code that’s hard to follow. An agent has to find out what code does before it can change it safely. Anthropic’s costs page treats that reading as a cost in its own right. It suggests a skill that describes a project’s architecture, so that Claude doesn’t spend tokens reading file after file to work out the structure. Messy code makes the reading longer in ways a developer will recognise:
- Tangled logic puts more into the context. To change one branch of a deeply nested method, the agent reads the whole method and follows each path through it. S2 Cyclomatic Caps puts a hard limit on that in the linter.
- Duplication means more places to find and change. Miss a copy and the task needs another round of reading and editing. F3 Don’t Repeat Yourself gives every fact one home, and TA2 Duplication Detection finds the copies that get past review.
- Vague names mean opening files to learn what something does. A function called
processsays nothing about its job, so the agent reads its body to find out. F2 Intention-Revealing Names asks for names that say what the code does. - Long functions mean bigger reads. Changing a few lines of a long function means reading the rest of it too. F1 Single Responsibility Principle keeps each function to one job.
Names have evidence of their own. Xin Shen and colleagues at Nanjing University tested them in On the Lexical Superstition of Large Language Models for Code Comprehension (2026). They renamed the identifiers in working code step by step, without changing what the code did. Across the models and comprehension tasks they tested, performance generally fell as names lost their information or became misleading. Answers often followed whatever a misleading name suggested.
That study measured accuracy and didn’t count tokens, but it shows how much models lean on names. None of this is new. Messy code has always been slow for people to work in for the same reason. With an agent, the extra reading is counted and billed.
What Sonar’s study measured
Priyansh Trivedi and Olivier Schmitt of Sonar published a controlled minimal-pair study of code cleanliness and coding agents in May 2026. A minimal pair is two versions of one repository with the same architecture, dependencies and behaviour. They differ only in their static-analysis findings and their cognitive complexity (Sonar’s measure of how hard code is to follow). One agent pipeline cleaned up three public repositories, and another made three of Sonar’s own clean codebases messier.
Trivedi and Schmitt wrote 33 tasks across the six pairs and ran each one ten times on each side. That made 660 runs of Claude Code with Claude Sonnet 4.6. The agents passed about the same share of tasks on both sides: 91.3% on the cleaner code and 92.1% on the messier code. On the cleaner side they used 7.1% fewer input tokens and 8.5% fewer output tokens.
Revisits changed most. In a revisit, the agent reads a file again after it has already read and edited it. Revisits fell by about a third, and Trivedi and Schmitt read that as less uncertainty about earlier edits. Split by track, the results didn’t agree:
| Tasks | Input tokens | Files read | Revisits |
|---|---|---|---|
| All 33 tasks | 7.1% fewer | 3.2% more | 33.8% fewer |
| Across two or more modules (14 tasks) | 10.7% fewer | 0.6% fewer | 50.8% fewer |
| Inside one dense method or class (13 tasks) | 1.8% more | 11.2% more | 20.2% fewer |
Each figure, from the paper’s tables 2 and 3, compares the cleaner side with the messier side. Six more tasks were built so that cleanliness shouldn’t matter, and count only in the first row.
Sonar’s own write-up, Killian Carlsen-Phelan’s Your AI bill is a code quality problem (2026), reports the headline figures. Two details in the paper change how to read them:
- Across all the tasks, agents read slightly more files on the cleaner code, 3.2% more. The saving lines up with going back to files less often.
- Sonar’s paper counts tokens. Its authors say the saving in money will be a different size, because the price depends on which model and provider you use and on the state of the cache.
Trivedi and Schmitt list the other caveats themselves. Every result comes from one model running in Claude Code. They built every pair and wrote every task. Their paper reports no significance tests. Carlsen-Phelan’s post adds that the effect swung from 47% fewer input tokens to 44% more between tasks. Of the 27 tasks outside the calibration set, 16 favoured the cleaner side.
When splitting code costs more tokens
One track went the other way, with a direct bearing on a rule set like Prickles. Its tasks sat inside one dense method or class. On the cleaner side, the cleanup had pulled that logic out into helpers. There, agents used 1.8% more input tokens and read 11.2% more files. The paper’s explanation:
extraction redistributes complexity across more methods rather than eliminating it
That result goes against part of the Prickles canon. S2 Cyclomatic Caps holds every function to a cyclomatic complexity of 3 and 15 lines in the packs’ lint configs, so code ends up in small functions. Sonar’s hotspot track is evidence that splitting code into more, smaller pieces doesn’t save tokens on its own, and can cost slightly more.
Against bad extraction, the canon has only a narrow guard. S5 Inline-First rejects a one-line helper with one caller and a name no clearer than its body, and anything bigger passes it. Carlsen-Phelan’s post describes what that leaves open. On one task in the genie repository, the cleanup pulled helpers out around the logic the task needed and left that logic where it was. The core was no easier to find, and agents used 8% more input tokens.
Prickles answers it with F1 Single Responsibility Principle. F1’s rule treats the size caps as early warnings for tangled code. Where to cut depends on which job each piece does, and who would ask for it to change. A name that says what each piece does then lets the agent search for it. In the example Sonar’s paper gives, an agent should find a method called normalize_query more easily than one called _xfm_q2.
That last step rests on reasoning alone. Sonar didn’t compare splitting by responsibility with splitting by size. The research for this article found no study that has.
What’s been measured and what hasn’t
| Claim | Status | Basis |
|---|---|---|
| Agents use fewer tokens on cleaner code | Measured: 7 to 8% fewer, one model | Sonar’s paper |
| Agents use 35 to 45% more tokens on unhealthy code | Claimed, with the data unpublished | CodeScene’s blog |
| Splitting one dense method into helpers can cost more | Measured: 1.8% more input tokens | Sonar’s paper |
| Vague or misleading names hurt how models read code | Measured for accuracy, with tokens uncounted | Shen and colleagues |
| Savings per task add up over months of work | Not measured | Sonar names it as the next question |
| Lint feedback lowers an agent’s total tokens | No study found | None |
| The Prickles rules cut token spend | Not measured | None |
My argument has two halves. Getting a codebase clean costs tokens at the start, because something has to read it and fix it. Once it’s clean, every later task should cost less. Sonar’s study supports the second half for single tasks. Its authors name the long run as the next thing to measure, since savings could build up over time or the code could drift until they’re gone. Prickles hasn’t measured what its own rules do to a token bill either, so this article puts no number on it.
Rule files add a separate, fixed cost. CLAUDE.md, AGENTS.md and the rest go into the context at the start of every session, whatever state the code is in. CLAUDE.md vs AGENTS.md covers the cost of keeping two of them.
How to reduce token usage from the code side
- Name each function and value for what it does, in the project’s own words, so an agent can find it by searching (F2 Intention-Revealing Names).
- When a function trips the linter’s caps, split it along a responsibility and give each piece a name that makes sense on its own (F1 Single Responsibility Principle). Leave a one-line helper with one caller inline (S5 Inline-First).
- Keep one copy of each piece of logic, and run a duplication check in CI to catch the copies (F3 Don’t Repeat Yourself and TA2 Duplication Detection).
- Make every limit a linter error, so the agent hears about a breach while it’s still working in the file (TA1 Linter as Law).
- Measure on your own code before you trust anyone’s percentage, Sonar’s included.
Step 4’s evidence concerns following rules. It says nothing yet about tokens. Yujun Zhou and colleagues tested coding agents in Getting Better at Working With You (2026). Rules turned into checks that had to pass were met 70.1% of the time, against 55.0% for the same rules given as text. The research for this article found no study showing that lint feedback lowers an agent’s total tokens.
For step 5, one run proves nothing. Bai and colleagues found that runs of the same task can differ by up to 30 times in total tokens. Sonar ran every task ten times on each side, and its paper cites the same study on how much runs vary. Claude Code’s headless mode prints a run’s usage as JSON:
claude -p "<the task>" --output-format json > run-01.json
Anthropic’s Run Claude Code programmatically and Track cost and usage (both 2026, read on 12 October 2026) describe the output. total_cost_usd gives an estimate worked out on your machine. Your bill can differ from it. The usage block counts input_tokens apart from cache_creation_input_tokens and cache_read_input_tokens. It leaves out any subagents the run started.
Run the same task on the messy version and on the cleaned-up version, reset the working tree between runs and compare the medians. Record whether each run passed as well, and compare pass rates alongside tokens, as Sonar did.
