An AI coding agent asks the same sort of question hundreds of times a day: where is this function called, which files mention that setting. A plain rg answers each one by reading every file again. That is fine on one repository. It gets slow when you run many checkouts on one machine, which is our situation.

So we built unumsearch, a search CLI for code and files that keeps an index and answers like ripgrep, usually in milliseconds. It is open source (Apache-2.0), written in Rust, and has no GPU, model or network dependency. This post is what it does, what we measured, and where it loses.

How it works

The index is a list of every three-letter piece of text and the files it appears in. A query is cut into those pieces, the index names the few files that contain all of them, and only those files are opened and checked line by line against their real contents. The index only narrows what to read; the answer always comes from the file.

Two properties matter for agents:

  • It says when it might be stale. A file watcher marks edits, changed files are searched directly until the index catches up, and every JSON answer carries fresh, backend, covered, truncated and complete fields so a client knows when to scan for itself.
  • It does not index secrets. .ssh/, .aws/, .env*, *.key, *.pem and similar are never indexed, whatever the configuration says.

What we measured

The test set is 20 regexes mined from a week of real coding-agent tool calls, on the author's machine, dated 2026-10-09.

Over the whole tree (247,535 files, warm page cache, median of three passes), ripgrep 15.1 took 347 ms per query. The unumsearch daemon took 64 ms and the one-shot CLI took 91 ms.

In a separate race of 12 patterns our agents actually issued, over about 180 worktrees (258k files), ripgrep needed 4.03 s in total and the daemon needed 217 ms, 18.6x faster, with the same files as rg on 12 of 12.

On answers: 19 of 20 queries returned exactly rg's files; the 20th differs only by .env.example files, which unumsearch never indexes on purpose. During git checkout of a branch that rewrites 44,686 Linux kernel files, the index caught up 6.4 to 7.5 s after the checkout began. Until then answers said fresh: false, and 0 of 64,454 fresh answers differed from ripgrep.

Where it loses

On a single repository of 3.7k files, ripgrep takes a median 9.8 ms. The daemon takes 2.3 ms, but the one-shot CLI, which starts a new process per query, takes 12 ms. That is slower than rg. The speed comes from a process that keeps the index open, so if you run it as a daemon, MCP server or rpc, you get the gain; if you shell out once per query on a small repo, you do not.

The benchmark file lists further weak spots, including that a busier machine made every engine about 1.7x slower in one run, so read the absolute times with that in mind.

Try it

curl -fsSL https://github.com/corpunum/unumsearch/releases/latest/download/install.sh | sh unumsearch --root ~/src/myrepo index unumsearch search 'fn\s+main' ~/src/myrepo --text 

For agents, unumsearch mcp runs it as a stdio MCP server, and the README lists setup for Claude Code, Codex CLI, Gemini CLI and others. The latest release at the time of writing is v0.1.12, which fixed a case where a daemon reported fresh before it had looked at its roots.

You can reproduce the race on your own code with python3 bench/race.py --root .; your numbers will differ.

Source and benchmark method: github.com/corpunum/unumsearch.

How this was written

This article was drafted by an AI model (Claude, from Anthropic) working for CorpUnum Labs, from the project's README, benchmark notes and published project facts. Its figures were checked against those files before posting. The numbers come from those files; none were measured by the model.

We are CorpUnum Labs, in Athens, building OpenUnum, a local-first runtime for user-owned agents. If you want to see what our agents do on that one mini PC, there is a playable lab here: corpunum.com/play.