On this page
- Why this page is built this way
- 1. Finding the right files
- How this number moved
- 2. What changes in a real agent loop
- The column that is not about any tool
- Why tokens and not dollars
- Where the saving is largest
- 3. Loading one commit's context
- 4. Command-output compression
- 5. Code health predicts defects
- 6. Indexing time, the row we lose
- Limits
Why this page is built this way
In July 2026, JetBrains took two popular token-saving tools and reran their headline claims on real agent work. Caveman advertised a 65% saving and measured 8.5%. RTK advertised 60 to 90% and came back 7.6% more expensiveat low reasoning effort. Greptile's 82% became 45%under Augment's rerun.
Three independent collapses is not bad luck. In this category the advertised number and the reran number are routinely different numbers, and they are different for a reason worth understanding before reading anything below.
Measuring one context load is easy. Measuring an agent loop is hard.
You can show that your representation of a file is smaller than the file. That is a real measurement and it is the one almost everybody publishes. It is also not the question anyone actually has, which is whether an agent given your tool finishes the job having done less work. Agents re-read, backtrack, re-plan and re-explore. A compression that looks like 90% on one payload routinely nets out near zero across a real session, and can go negative when the agent has to work harder to recover what you compressed away.
This page publishes both numbers and labels which is which. Section 3 is the one-payload figure. Section 2 is the agent-loop figure, and it is deliberately the smaller one.
One payload, not a session. It says our representation of a commit is smaller than the commit. Whether an agent finishes faster is a different question, and its answer is the more modest 31.6%. One repository, one commit, one prompt, and single-session questions of four to seven turns. Not a universal saving.
1. Finding the right files
Before a tool can save an agent any work, it has to point at the right code. This section measures only that. Grading is deterministic and no LLM judge is involved anywhere in the number, which makes it the most reproducible result on the page: ContextBench ships gold file spans, and a tool either returns them or it does not.
Every figure below comes from instances this work has never seen. The 112 instances were split 70 / 42 by instance id, pinned before any of it started, and the 42 were kept sealed until the final measurement.
Finding the right files
File coverage on 42 ContextBench instances pinned before any of this work started and kept sealed until the final measurement. Grading is deterministic and no LLM judge is involved.
| Tool | File coverage | Precision | Files served |
|---|---|---|---|
| repowise (get_answer) | 0.876 | 0.087 | 19.2 |
| repowise (search_codebase) | 0.742 | 0.168 | 8.2 |
| CodeGraph | 0.610 | 0.093 | 14.0 |
| Graphify | 0.546 | 0.033 | 34.5 |
| code-review-graph | 0.445 | 0.240 | 5.4 |
Scroll the table sideways to see every column.
n = 42 sealed instances. Head to head against CodeGraph, get_answer wins 19, loses 1, ties 22, sign test p = 0.00004. The pooled 112-instance figure would be 0.835 and is deliberately not quoted: averaging the halves loses the only number that matters, which is how the tool does on instances it has never seen.
These are two different tools with two different profiles, and we would rather say so than average them into one claim. get_answer finds the most, from a list of about 19 files. search_codebase finds fewer but is the most efficient per file served, and if you are paying by the token that is the row to read.
| Tool | File coverage | Files served |
|---|---|---|
| repowise (get_answer) | 0.876 | 19.2 |
| repowise (search_codebase) | 0.742 | 8.2 |
| CodeGraph | 0.610 | 14.0 |
| Graphify | 0.546 | 34.5 |
| code-review-graph | 0.445 | 5.4 |
n = 42 sealed instances. Head to head against CodeGraph, get_answer wins 19, loses 1, ties 22, sign test p = 0.00004. The pooled 112-instance figure would be 0.835 and is deliberately not quoted: averaging the halves loses the only number that matters, which is how the tool does on instances it has never seen.
How this number moved, and why it is not benchmark tuning
We first ran this and came last, at 0.228. We published that. The cause turned out to be a bug: a query-time gate was discarding most candidates before ranking ever happened. Fixing that path is what moved the number, and it is a fix any user of the tool gets rather than a change shaped around these questions.
The check on that claim is the split, and it points the right way. Our score on the sealed half we never saw, 0.876, is higher than our score on the half we tuned against, 0.810. Overfitting makes the unseen half score worse.
And CodeGraph, which nobody tuned against either half, scores 0.6093 and 0.6095 on the two halves. Three decimal places apart. So the halves are equally hard and the gap is about the tool rather than about the questions.
We do not quote a pooled 112-instance figure, though it is easy to compute and would read 0.835. Averaging the halves loses the only number that matters, which is how the tool does on instances it has never seen.
Every arm builds its own index of every instance's repository at that instance's own base commit. Roughly 78 machine-hours for 1,129 graded cells. How we measured · raw data
2. What changes in a real agent loop
This is the section modelled on the JetBrains reruns, and the one we would ask a skeptic to read first. Six arms: repowise, four competing tools, and a bare agent with no tools at all. Every arm got a byte-identical prompt, its full advertised tool surface, and a freshly built index on the same pinned commit. The bare-agent control was verified free of any local hooks, so it is a real control rather than a contaminated one.
Two things have to be true for a tool to be worth mounting. The agent has to actually call it, and the loop has to get leaner when it does. We ran this on two agent harnesses, because the answer turned out to depend on the harness as much as on the tools.
| Tool | Output tokens | vs bare agent |
|---|---|---|
| repowise | 1,250 | -31.6% |
| CodeGraph | 1,383 | -24.4% |
| Serena | 1,550 | -14.8% |
| Graphify | 1,658 | -8.9% |
| code-review-graph | 1,710 | -6.0% |
| bare agent (control) | 1,828 | baseline |
Codex (gpt-5.6-sol) on django/django at one pinned commit. Correcting for testing five tools at once, three reductions are solid and two are marginal. 5 of the 48 questions are missing from every arm equally because the run hit an API usage cap, so the figures are over the 43 questions all six arms completed; because all arms lost the same 5, the paired comparisons are unaffected.
What changes in a real agent loop, on Codex
Every question in django's question set, six arms, byte-identical prompts, each tool's full advertised surface, and a freshly built index on the same pinned commit. Every tool was called on every question, so this is like for like.
| Tool | Agent used it | Output tokens | vs bare agent | Tool calls | Leaner on | p |
|---|---|---|---|---|---|---|
| repowise | 44 / 44 | 1,250 | -31.6% | 3.8 | 37 of 44 | <0.0001 |
| CodeGraph | 44 / 44 | 1,383 | -24.4% | 4.0 | 37 of 44 | <0.0001 |
| Serena | 43 / 43 | 1,550 | -14.8% | 10.1 | 35 of 43 | <0.0001 |
| Graphify | 43 / 43 | 1,658 | -8.9% | 7.4 | 31 of 43 | 0.003 |
| code-review-graph | 43 / 43 | 1,710 | -6.0% | 7.2 | 26 of 43 | 0.046 |
| bare agent (control) | 0 / 44 | 1,828 | baseline | 7.2 | n/a | n/a |
Scroll the table sideways to see every column.
Codex (gpt-5.6-sol) on django/django at one pinned commit. Correcting for testing five tools at once, three reductions are solid and two are marginal. 5 of the 48 questions are missing from every arm equally because the run hit an API usage cap, so the figures are over the 43 questions all six arms completed; because all arms lost the same 5, the paired comparisons are unaffected.
repowise leaves the agent with the least work to do, and gets there in the fewest steps: 3.8 tool calls against the bare agent's 7.2, and 3.0 files opened instead of 7.2. One answered question replacing roughly six greps, visible directly in the call counts rather than inferred.
Correcting for testing five tools at once, three reductions are solid and two are marginal. CodeGraph is a genuine second at -24.4%, and the honest reading is that we lead a field in which more than one tool works, not that we are the only one that does. Serena is the interesting counter-case: it writes less than the bare agent while calling tools 42% more often. Busier, not leaner.
The second proof point, on Claude Code
The same six arms, the same servers and the same indexes, on a different agent harness. The result depends on the harness as much as on the tools.
| Tool | Tools advertised | Schema cost (chars) | Agent used it | Output tokens | vs bare agent | p |
|---|---|---|---|---|---|---|
| repowise | 10 | 17,561 | 15 / 15 | 2,420 | -15.9% | 0.035 |
| CodeGraph | 1 | 1,567 | 13 / 15 | 2,540 | -11.7% | 0.302 |
| Serena | 29 | 29,050 | 4 / 15 | 2,551 | -11.3% | 1.000 |
| code-review-graph | 30 | 28,118 | 0 / 15 | 2,768 | -3.8% | 0.302 |
| Graphify | 10 | 5,482 | 3 / 15 | 2,878 | 0.0% | 1.000 |
| bare agent (control) | 0 | 0 | n/a | 2,877 | baseline | n/a |
Scroll the table sideways to see every column.
Claude Code (claude-sonnet-5), 15 questions. Treat the "agent used it" column as unstable, including our own 15 of 15: rerunning the same setup on later days returned 4 of 15 and then 3 of 15 for us, and 2 of 14 for CodeGraph. It is a property of the pairing of tool and harness on a given day, not of the tool. No quality or cost figure may be compared across the two harnesses, which were graded by different judges.
The column that is not a fact about any tool
Under Claude Code most of these tools were barely called at all. code-review-graph never once, Graphify three times in fifteen. Nothing was different about the servers, the questions or the indexes between the two runs. Claude Code loads MCP tool schemas on demand, so the agent has to go looking before it can call anything, and frequently never does.
Treat that column as unstable, including our own 15 of 15.
Rerunning the same setup on later days returned 15 of 15, then 4 of 15, then 3 of 15 for us, and 2 of 14 for CodeGraph. Whether an agent calls a codebase server at all depends more on the harness than on the server. We used Sonnet here, and Sonnet reaches for MCP tools noticeably less than Codex does under an identical setup, so harness and model cannot be separated by this design. We plan to rerun this half on Opus and will add the result when we have it.
One thing this run does not show: it is a work-saved result, not a quality result. A blind judge scored every tool in the field, ours included, a fraction below the bare agent, in a range of 0.04 to 0.25 points on a 10-point scale. None of those differences is statistically distinguishable from zero, and all of them are smaller than the 0.69 points by which this benchmark moves when we rerun it unchanged. Ours is at the low end of that band, we are watching it, and we will say so if it turns into a real effect.
Why this section reports tokens and not dollars
Dollar cost per question is the number every tool in this category wants to quote, and it is close to meaningless as a measure of a tool. Here is the control that convinced us, run in our own harness.
A tool that did nothing came out 43% cheaper than the bare agent.
Under Claude Code, code-review-graph never called its server across all 15 questions. It is behaviourally identical to the bare agent, carrying an extra 28,118 characters of tool schema that should make it cost more. Measured on dollars, it produced a best-in-class saving.
The cause is prompt caching. Cached tokens bill at a fraction of fresh ones, so whichever arm happens to run first pays to warm the cache and every arm after it reads it cheaply. In our run the correlation between an arm's position in the cycle and its dollar cost was -0.487. That is not a property of any tool. It is a property of the schedule.
Output tokens are immune to this. They are never cached, and their correlation with run position is +0.010, which is nothing. So that is what we report. It is a smaller and less impressive number than the dollar figure would have been, and it is the one that survives. If you see a token-savings claim in this category that does not say whether it controls for cache state and arm ordering, this is the first thing to ask about.
Where the saving is largest
The effect is not uniform. repowise saves more on questions that require touching more of the codebase. Splitting the question set at the median by how much work the bare agent needed, the harder half saved 34.3%against the easier half's 27.2%, more than twice as many tokens per question, and the correlation between how much work a question demands and how much we save is +0.379. The mechanism is that pre-computed structure replaces exploration, and harder questions contain more exploration to replace.
Two honest limits on that. The median split was chosen after seeing the data, so it is post-hoc and weaker evidence than the pre-registered comparisons. And every question here is answered in a single session of roughly four to seven turns: we have not measured a long multi-hour task such as designing a feature across many files, and we will not imply a number for one.
About 13 hours of machine time and roughly $44 of API spend. Around a third of those runs are proof-of-life checks rather than headline numbers. How we measured · raw data
3. Loading one commit's context, the easy number
This is the measurement almost every tool in this category publishes, and we are labelling it as such. It is a real measurement. It is not section 2, and it should not be read as though it were.
Loading one commit's context
The measurement almost every tool in this category publishes, labelled as such. Counted with deterministic tiktoken over the 30 most recent non-merge commits of pallets/flask.
| Strategy | Tokens per commit |
|---|---|
| naive, full contents of every changed file | 13,984 |
| git diff only | 1,408 |
| get_context | 393 |
Scroll the table sideways to see every column.
35.6x fewer than naive pooled, 29.3x as a mean of per-commit ratios, and 3.6x pooled against git diff. This is one payload, not a session. It says our representation of a commit is smaller than the commit; it does not say an agent finishes faster.
Lead with the pooled figure. Pooled is sum-of-tokens over sum-of-tokens, so it weights each commit by the tokens actually at stake. A mean of per-commit ratios does not: a one-line commit where get_context returns 40 tokens contributes a huge ratio that counts equally against a commit saving a hundred thousand. That is exactly how a 35x becomes a 209x in a press release, and it is why the pooled number is the one we print first.
4. Command-output compression
repowise distill compresses command output before the agent reads it: errors first, exit code preserved, every omission recoverable through an inline marker. A pytest run with 11 failures compresses 61% with all 11 failure lines kept, and a 30-commit diff compresses 86%.
Two commands in the same set saved 0%, because distill never inflates output that is already compact. Reduction is also not comprehension: the bytes removed are measured, and the evidence they were safe to remove is narrower, being preserved failure lines plus CI-asserted fixtures.
5. Code health predicts defects
A health score is worth something only if the files it flags are the files that break. Scores are taken at a historical commit, bug fixes are counted over the following six months, and nothing after the scoring commit feeds the score. Across 21 repositories, 9 languages and 2,826 files that gives an ROC AUC of 0.74, reaching 0.90 on individual repos. It survives controlling for file size, so it is not simply flagging the big files, and it beats recent churn by +0.10 AUC.
Code health against CodeScene
Both tools scored the same 2,770 files at the same leakage-free commit against the same defect labels. Paired tests throughout.
| Paired test | repowise | CodeScene | p |
|---|---|---|---|
| Recall at a 20%-of-lines review budget | 0.173 | 0.074 | 0.003 |
| Effort-aware ranking (Popt) | 0.607 | 0.462 | 0.003 |
| Defect density, size-normalized (Alert:Healthy) | 2.18x | 0.56x | 0.003 |
| Discrimination (ROC AUC) | 0.731 | 0.705 | 0.054, marginal |
| Precision at a 20%-of-lines review budget | 0.580 | 0.636 | 0.64, a tie |
Scroll the table sideways to see every column.
CodeScene's precision lead is not statistically significant, but the behaviour behind it is worth having: it flags about 27 files where we flag 132. That is a more conservative threshold, trading recall for a short list a team will actually work through, and it is a deliberate design choice rather than a weaker model. Our AUC edge is marginal, not significant at 0.05.
Where CodeScene is ahead, it is a real choice rather than a weaker model. Its nominal precision lead is not statistically significant, but the behaviour behind it is worth having: it flags about 27 files where we flag 132. That is a more conservative threshold, trading recall for a short list a team will actually work through. If what you want is a handful of files to fix this quarter rather than the ranking that catches the most defects, that operating point is the better one.
6. Indexing time, the row we lose
We are the slowest indexer in the field, on every repo we measured, and it is not close. The reason is not an optimisation we forgot: the tools we are measured against build a call graph, and in the same pass we also mine git history, generate and embed documentation, extract decision records and score code health.
Indexing time, the row we lose
We are the slowest indexer in the field, on every repo we measured, and it is not close. Measured on django/django.
| Tool | Index time | What it builds |
|---|---|---|
| CodeGraph | 16.4s | call graph |
| code-review-graph | 44.8s | call graph |
| Graphify | 141.5s | call graph, communities |
| repowise (--no-prose) | 366.8s | graph, git history, decisions, code health |
| repowise (default, prose on) | 1,058s | all of the above plus generated documentation |
Scroll the table sideways to see every column.
22x CodeGraph like for like, and 135x with prose on, which is what a default repowise init actually costs you. Both numbers ship. The reason is not an optimisation we forgot: in that same run repowise built 36,485 graph nodes, mined history across 2,630 files, rendered and embedded 3,392 wiki pages, extracted decision records and produced 5,317 health findings. It is also a one-time cost, since updates after the first index are incremental.
So "22xslower" and "the index contains categorically more" are both true, and neither one cancels the other.
If all you want is a call graph, CodeGraph builds one in 16 seconds and you should use it. The comparison that would be dishonest is quoting the ratio without the column beside it, which is why the column is there. It is also a one-time cost: updates after the first index are incremental.
Limits
Beyond the ones stated in each section:
- Python and Go only. No TypeScript or JavaScript row appears anywhere on this page. That was a scope choice made for instance density in the benchmark corpus, not a statement about language support.
- Section 2 is one repository at one commit, which is in every model's training data.
- Nothing here measures a long engineering task. Every question is a single session of roughly four to seven turns.
- Two capability rows are not measured at all: documentation generation against DeepWiki, Google Code Wiki and Swimm, and PR review against CodeRabbit and Greptile. We would rather say "not measured" than let a checkmark do a number's job.
The full methodology, the pre-registration files with their commit timestamps, the arm-parity rules, the statistical tests, and the list of measurement traps that produced wrong numbers before we caught them all live in repowise-bench. That repository also holds every raw run, kept permanently, including the invalidated ones with their invalidation notes attached.