LabAtrius

A code index, measured against ripgrep

Agents search code with ripgrep. We built an index that returns exactly ripgrep’s lines from memory, kept current as files change, and measured it against ripgrep and four other tools on frozen query sets, then on 19 open source repositories in 13 languages. It is now Atrius, a command line and an MCP server for Windows, macOS and Linux.

140×ripgrep
median query on Linux, held in the agent’s MCP process; 32× to 40× on three smaller repositories
2,200of 2,200
queries on 19 open source repositories with ripgrep’s exact lines
0stale
results after edits, renames, deletes, bursts of files and branch switches
0.95× tokens
whole agent session, Sonnet, against a goal of 0.50

The index returns ripgrep’s exact lines 32 to 140 times faster, and stays correct through every kind of change. It leaves an agent’s accuracy and token cost where ripgrep leaves them: a capable model already uses ripgrep well enough that the cost of a session is mostly its instructions.

01The question

Can an index beat ripgrep for an agent?

Three goals were set before anything was measured: five hundred percent faster, half the tokens, and ten percent more accurate. Seven query families were frozen and hashed: names to find, grep patterns agents really ran, uses of a name, files by name, tickets to localise, questions in plain English, and questions the code cannot answer. Every timing was pinned to the same processor cores, and a run was refused when the machine was busier than a quiet reference.

Three goals, frozen before the first run

The goals and the query sets were hashed before any result and never changed. 30% of every query set was held out and used only for the final gate.

GoalBarResultVerdict
Speedat least 6.0× ripgrep, lower end of the 95% interval too26.7× to 36.1× on three repositories, 128× to 136× on Linux, three gate runs from cold hostsPasses
Tokensagent session at most 0.50× the ripgrep arm0.95× on Sonnet, 0.98× on OpusNot reachable by construction
Accuracyagent success at least 1.10× ripgrep, no family worse0.689 against 0.678 on Sonnet; exact families equal or betterNot met
02Results

Fast and exact. No help with tokens.

  • Held in the agent’s own MCP process, the index answered in a median 1.0 to 2.0 ms on three repositories against ripgrep’s 43 to 50 ms, and 6.1 ms against a second on the Linux kernel, with ripgrep’s exact lines on every one of 468 held out queries.
  • Most of that lead on Windows is ripgrep’s Windows cost: a process start and file system calls on every search. In WSL ripgrep took 4 to 6 ms a query, and Zoekt, the trigram engine this design follows, 0.5 to 1.1 ms.
  • Definitions are found at the first place about twice as often as a whole word ripgrep search finds them there: 0.50 to 0.83 against 0.21 to 0.36.
  • Whole session tokens do not halve. Sonnet and Opus finish in five to seven turns with either tool, and each turn sends about 5,200 tokens of instructions and tool definitions again. Haiku, which takes three times as many turns, saves about a quarter.
  • One plain English search written from a ticket finds the right file less often than the Grep calls an agent writes after reading the code. The index helps most when the agent already knows a name to look for.
  • On 19 open source repositories in 13 languages, every one of 2,200 generated queries returned exactly ripgrep’s lines, and 54 of 54 hand checked definitions were found in the first three answers.

Against other tools, on the same machine

The 468 held out queries were grep patterns agents really ran, mined from 1,076 Claude Code sessions, plus names searched as whole words. Each ran once to warm up and three times timed. Zoekt does not build on Windows, so it ran in WSL against ripgrep there, which is ten times faster than ripgrep inside Claude Code on Windows: compare its absolute times.

Toolai-service, medianLinux 6.16, medianAgainst ripgrepSame lines as ripgrep
ripgrep in Claude Code50.11 ms999.84 ms1×all
The index, in the agent’s MCP process1.96 ms6.11 ms32× to 40×, 140× on Linuxall 468
The index, through a separate host4.91 ms75.87 ms9.5× to 10×, 15× on Linuxall 468
ugrep with its own index22.22 ms661.60 ms1.7× to 1.9×, 1.4×92% to 97%
ugrep22.62 ms918.04 ms2.0× to 2.3×, 1.1×87% to 97%
git grep38.28 ms969.99 ms1.2× to 1.3×, 1.0×99% to 100%
Zoekt, in WSL0.58 ms1.06 ms5× to 6×, 51× against WSL ripgrep93% to 99%

What it does for an agent

Agents ran with no settings loaded and a fixed tool list: Grep, Glob and Read in one arm, the index and Read in the other. 121 held out tasks: tickets from our task board (which files does this change touch) and questions about the code.

ModelArmSuccessMedian session tokensMedian turns
Sonnet, 3 drawsripgrep0.67844,0245
Sonnet, 3 drawsindex0.68947,0655
Opus, 1 drawripgrep0.73666,5566
Opus, 1 drawindex0.70258,5017
Haiku, dev split, 2 drawsripgrep0.475577,68415.5
Haiku, dev split, 2 drawsindex0.513529,49616
03Real code

The same lines as ripgrep, in 13 languages

After the study the index became Atrius, and Atrius was tested on code other people wrote. Writing the test found two faults, both fixed: Lua writes its C functions with a space before the parameters, so they were not read as definitions, and vite’s createServer ranked behind eleven copies in its playground folder.

Nineteen repositories other people wrote

Each repository is pinned to a release tag. 120 queries per repository were made from its own text (40 on Linux): literals, case insensitive, whole words, calls, alternations, anchored regexes, phrases, and the same scoped by glob, type and path. Times are medians for one query: the index function in process, and ripgrep as a process with the Grep tool’s flags, which includes starting it.

RepositoryLanguageFilesEqual to ripgrepIndexripgrepDefinitions found
spf13/cobraGo67120 / 1200.50 ms15.95 ms3 / 3
lua/luaC111120 / 1200.50 ms16.78 ms3 / 3
psf/requestsPython130120 / 1200.49 ms16.11 ms4 / 4
BurntSushi/ripgrepRust213120 / 1200.56 ms17.25 ms4 / 4
expressjs/expressJavaScript226120 / 1200.49 ms17.00 ms3 / 3
sinatra/sinatraRuby293120 / 1200.47 ms16.87 ms2 / 2
google/gsonJava304120 / 1200.62 ms18.10 ms3 / 3
square/okhttpKotlin509120 / 1200.78 ms19.69 ms3 / 3
Alamofire/AlamofireSwift569120 / 1201.34 ms21.00 ms3 / 3
nlohmann/jsonC++1,091120 / 1200.99 ms29.34 ms3 / 3
JamesNK/Newtonsoft.JsonC#1,159120 / 1201.86 ms28.30 ms3 / 3
redis/redisC1,608120 / 1201.58 ms30.27 ms3 / 3
vitejs/viteTypeScript2,228120 / 1201.58 ms35.13 ms4 / 4
laravel/frameworkPHP2,544120 / 1202.14 ms35.69 ms2 / 2
django/djangoPython6,811120 / 1204.54 ms76.52 ms3 / 3
golang/goGo13,227120 / 1209.21 ms122.28 ms3 / 3
ziglang/zigZig17,712120 / 1205.95 ms161.14 ms2 / 2
scala/scala3Scala21,976120 / 12017.46 ms232.26 ms3 / 3
torvalds/linuxC89,66840 / 40525.65 ms785.26 msnone listed
04Experiments

One change at a time

What we tried, and what we kept

One change at a time, kept only when it won on the development split with no query family worse.

ExperimentSettingResultKept
Verifying candidateswhole files, then 64 KB blocks searched in place3.5 ms to 1.3 ms on a query with no hitsblocks
Regex to trigram plannerfixed a join across a wildcard898 to 899 of 900 agent patterns equal; the last one ripgrep refuses toofixed
Compactionoff the index lock, from a copylongest wait after a 5,000 file burst: 19.1 s to 69 msyes
Writing vectorsone transaction per batchfrom 4 to between 22 and 37 chunks a second per hostyes
Saying nothing matchesInillucent confidence, then word coverageconfidence turned every ticket away on code; word coverage below 0.31 keptcoverage
Fusing word and vector rankingsweighted 0.3, 0.5, 0.7, RRF, adaptiveall within a query or two; weighted 0.5 kept0.5
Ranking for plain Englishcode before documents in one searchF6 0.150 to 0.215 on one repositoryyes
What an answer carriessmall answers include the code around the hitHaiku token ratio 0.79 to 0.55, one drawyes

What we would do next

  • Use the index wherever an agent searches code on Windows, held in the agent’s own MCP process.
  • Do not expect it to cut an agent’s tokens or raise its accuracy on its own; those depend on how many turns the agent takes.
  • The weakest part is a single plain English search from a ticket’s words. That is the next piece of work.
  • The passage table makes the index file larger than the code it indexes; exact search does not need it.
05Get Atrius

Atrius 0.1.0

A command line, atrius, and an MCP server, atrius-mcp, for Windows, macOS and Linux. Free under the MIT or Apache 2.0 licence.

Windows
irm https://blackrainbowlabs.com/downloads/atrius-index/install.ps1 | iex
macOS and Linux
curl -fsSL https://blackrainbowlabs.com/downloads/atrius-index/install.sh | sh
Homebrew
brew install black-rainbow-labs/atrius/atrius-index
From source
cargo install atrius-cli
Connect an agent
claude mcp add atrius -- atrius-mcp

Every archive, the signed macOS installer, the .deb and .rpm packages and the signed checksums are in the downloads folder.