A claim has been circulating in engineering channels for most of this year: dynamically typed languages are cheaper to work with when AI coding agents are doing the typing. No type annotations means fewer tokens, fewer tokens means a smaller bill, and therefore Python and Clojure quietly beat Rust and Java on cost. Some teams have taken this seriously enough to raise it in architecture reviews.
An analysis published this month put the claim through a proper test, and it did not survive. The result is worth understanding, but the way the original claim was produced is the more useful lesson, because the same failure mode is showing up across a lot of AI tooling decisions right now.
TL;DR
- The viral claim that dynamic languages are 2.6x more token-efficient for AI coding agents came from toy problems solvable in 70 to 109 tokens, and it does not hold on realistic tasks.
- A widely cited benchmark had a broken test harness: a non-existent path skewed Rust’s scores, and a later Go implementation symlinked that same path so subsequent tests silently executed the Go binary.
- On genuinely hard tasks (a zstd decoder, a document converter), the static versus dynamic gap disappeared entirely, and obscure but token-dense languages such as J and Factor performed badly.
- Output tokens were never the cost driver. Agent loops are dominated by input tokens across repeated iterations, so a language that fails verification more often is more expensive regardless of how compact it looks.
- Model choice moves token cost far more than language choice, and you can change models next quarter. You cannot change your language next quarter.
The claim that got ahead of the evidence
The original evidence base was a set of small evaluations comparing how many tokens different languages needed to solve programming problems. The headline number, a 2.6x efficiency gap between C and Clojure, is real in the sense that it was measured. The difficulty is what it was measured on: problems that could be solved in 70 to 109 tokens.
At that size, syntax overhead is the whole signal. Type annotations and import blocks are a large fraction of a ten-line solution and a rounding error in a two-thousand-line module. Extrapolating from one to the other is the same mistake as benchmarking a database on a hundred rows and publishing conclusions about production workloads.
The follow-up work tested the same question on tasks with actual structure: implementing a zstd decoder, and building a Pandoc-style document converter. At moderate reasoning effort, dynamic languages did cluster slightly better on the cost-versus-correctness curve. At high effort, the picture went mixed, with static languages matching or beating dynamic ones depending on the task. Across both problems, no language family dominated, and the 2.6x gap was nowhere to be found.
The benchmark bug that matters more than the result
Buried in that analysis is a detail every technical leader should sit with. One of the benchmarks feeding the original claim had a test referencing a path that did not exist, which caused scoring failures attributed to Rust. Later in the same suite, a Go implementation created a symlink at that path. Every subsequent test that reached for it executed the Go binary instead of the language under test.
The benchmark was not measuring what it reported. It ran, it produced numbers, the numbers looked plausible, and they propagated into engineering conversations at companies that never inspected the harness.
This is the actual risk in the current tooling cycle. There is enormous appetite for data about AI-assisted development, very little of it is rigorous, and a chart with axes reads as authoritative long after the methodology has been discredited. We wrote about a related pattern in measuring developer productivity in the AI era: the metrics teams reach for are frequently the easy ones to collect rather than the ones that answer the question. Before a benchmark changes your architecture, someone on your side should be able to describe how it was run and what it did not control for. If nobody can, it is an anecdote with formatting.
Output tokens were never the cost driver
The deeper problem with the token-efficiency argument is that it optimises the wrong quantity. Watch what an agent actually consumes on a real task. It reads files, runs tests, reads the failures, reads more files, tries again. The code it writes is a small fraction of what passes through the context window. Cost is driven by input tokens multiplied by iteration count, and iteration count is driven by how quickly the agent can tell whether it is wrong.
Our own analysis of refactoring economics put numbers on the input side: splitting a 17,155-line file across nineteen smaller files cut input tokens per subsequent change from 159,564 to 27,360, an 83% reduction, with total lines of code essentially unchanged. Structure moved the bill by a factor of nearly six. Nobody deleted a type annotation.
Seen that way, a language that produces slightly more characters but fails loudly and early is cheaper than a compact one that fails at runtime three iterations later. Verbosity you pay for once. A missing feedback signal you pay for on every loop.
Static types are a verification subsidy
This reframes what type systems are worth in an agentic workflow. A compiler that rejects bad code before a test suite ever runs is a fast, deterministic, machine-readable oracle, and it costs nothing per invocation. That is precisely the resource agents are short of.
It connects to something we covered in the verification bottleneck. Generation is cheap and getting cheaper; confirming that generated code is correct is the expensive part. Anything that makes verification faster or more automatic is worth more than anything that makes generation marginally shorter.
That is an argument for static types, but equally for strict linting, exhaustive tests and schema validation at boundaries. The mechanism matters more than the language family: a well-instrumented Python codebase with strict mypy and Pydantic at the edges gives an agent better feedback than an untested Java service with permissive interfaces.
Obscure languages lose, and the reason is instructive
The most decisive finding was about the languages designed for density. J and Factor are extraordinarily compact, exactly the property the token-efficiency argument prizes. Both performed poorly.
The explanation is straightforward: models are good at what they have seen a great deal of. Training corpus depth beats notational economy, and it is not close. Language popularity turns out to be a weak but real predictor of agent performance, which is uncomfortable for anyone who enjoys niche tooling and genuinely useful for anyone making a commercial decision. Choosing an unusual stack to game token counts trades a small theoretical gain for a large practical loss in model competence, ecosystem tooling and, eventually, hiring.
Where the leverage actually is
If you want agents to be cheaper and more effective in your codebase, the levers that move the number are not linguistic.
Model selection. Reported token-efficiency differences between frontier models run to 48% to 76% on comparable work, with up to 47% fewer tokens on tool-heavy tasks. That dwarfs anything attributable to syntax, and it is a configuration change rather than a rewrite.
Codebase structure. Module size, file organisation and naming determine how much context an agent must load to make a change. The single biggest lever most teams have, and it is ordinary software engineering.
Feedback speed. Fast test suites, clear error messages, deterministic builds. Every second saved in the verification loop compounds across every iteration.
Codified conventions. Agent instruction files, architectural decision records and documented patterns reduce the exploratory reading that inflates input tokens, and the rework that inflates everything else.
Task scoping. Narrow, well-specified tasks converge. Vague ones loop. This is the difference between a predictable bill and an unpredictable one.
How to actually choose a language in 2026
Choose on the criteria that have always mattered, because they still dominate the economics: the depth of the hiring pool you can reach, the maturity of the ecosystem for your problem domain, operational fit with your infrastructure, and the maintenance horizon of the system you are building.
Run the arithmetic before you let token costs into the conversation. Even an aggressive estimate of language-attributable savings is hundreds or low thousands of euro annually for a typical SME build. One bad stack decision costs a senior salary in remediation, or a migration project. The two quantities are not in the same category.
Coding agents now leave traces in somewhere between 22% and 29% of active GitHub projects, based on a February 2026 study of 128,018 repositories. This is normal infrastructure, not an experiment, and it deserves the same evidentiary standard as any other infrastructure decision. That standard is not “a benchmark on the internet said so”.
Measure your own numbers
Nobody else’s benchmark describes your codebase. The number worth tracking is token cost per merged change, segmented by task type. Instrument it for a quarter and you will find your expensive areas are specific modules, specific kinds of task and specific gaps in your test coverage. They will not be your choice of language.
At REPTILEHAUS we make stack decisions for clients on maintainability, team fit and total cost of ownership, then optimise the AI-assisted workflow on top of whatever we chose. That ordering is deliberate: the workflow is adjustable in weeks, the stack is a five-year commitment.
If you are weighing a stack decision, auditing your AI tooling spend, or trying to work out why your agents burn tokens on some parts of the codebase and not others, get in touch. We are happy to look at the actual numbers.
📷 Photo by Florian Olivo (@florianolv) on Unsplash

