Scout, ripgrep, and GNU grep measured
Measurements cover dotnet/runtime v9.0.0 — 59,319 files, 30,172 of them C#.
The lexical tables compare Scout with ripgrep and GNU grep under the stated conditions.
These are historical measurements. The Environment section identifies the package versions and dates; results do not describe every new release.
Read the conditions beside each table. Hardware, methodology, and raw results follow the measurements.
Additional Scout search modes
Each number is the median of 10 runs on a warm index.
| Search type | What you ask | Scout |
|---|---|---|
| Fuzzy file discovery Finds the file even when you only remember part of its name. | httpclientfactory | 14.3 ms |
Code shape Matches how the code is written, not just the text. $$$ stands for “any arguments”, so this one finds every throw of that exception however it was constructed — and skips the same words inside a comment or a string. | throw new ArgumentNullException($$$) | 13.5 s |
| Symbol outline Lists declarations: names, kinds, and where they live. | HttpClient | 2.2 s |
| Semantic Ask in plain English; finds code that says it in different words. | “where request retries are limited” | 628 ms |
| Semantic Ask in plain English; finds code that says it in different words. | “cancellation token propagation through async streams” | 622 ms |
- Semantic search needs a one-time setup (start Scout with
--semantic); the cost is in the table below. - The code-shape and symbol-outline searches read every file Scout has a grammar for, which needed
limits.find-budget-msandlimits.structural-parse-capraised above the shipped default. Out of the box the same search stops earlier and reports how far it got. The other rows in this table ran on the shipped limits: neither limit bounds a fuzzy or a semantic search.
Text search speed
All three tools read every file. Each number is the median of 10 runs.
| Search | Scout | ripgrep | GNU grep | Matching lines |
|---|---|---|---|---|
Literal, commonpublic static | 372 ms | 788 ms | 17.2 s | 165,310 |
Literal, rareConfiguredCancelableAsyncEnumerable | 347 ms | 764 ms | 17.0 s | 33 |
Regexasync Task<\w+> | 407 ms | 778 ms | 17.0 s | 774 |
Word boundaryDispose | 354 ms | 778 ms | 17.5 s | 10,965 |
Case-insensitive literalhttpclient | 342 ms | 752 ms | 17.3 s | 3,181 |
What the index costs
Scout pays these once per repository. ripgrep and grep pay nothing up front, but pay the full search cost on every single call.
| Index ready in | Semantic setup | First-ever search | Memory |
|---|---|---|---|
| 2.2 s | 9.9 h | 2.6 s | 175 MB (6241 MB with semantic on) |
- Index ready in = start Scout in a repository it has never seen, and wait until search fully works.
- First-ever search = the very first search in that fresh repository, including startup and index building. Every search after it uses the warm numbers above.
- Semantic setup is the slow one: Scout downloads a model once, then reads through the whole repository. 0.87 GB of code took 9.9 hours (about 88 MB per hour). Plan from your own repository size. Until it finishes, semantic questions are answered by plain text search instead.
How many searches before the index pays for itself
Build the index once, and every later search is cheaper. This is how many searches it takes until that one-time cost has paid off against ripgrep.
| Query | Break-even | Scout per query | ripgrep per query |
|---|---|---|---|
| Literal, common | 6 searches | 372 ms | 788 ms |
| Literal, rare | 6 searches | 347 ms | 764 ms |
| Regex | 6 searches | 407 ms | 778 ms |
| Word boundary | 6 searches | 354 ms | 778 ms |
| Case-insensitive literal | 6 searches | 342 ms | 752 ms |
- Simple math from the numbers above: index build time divided by the time saved per search. Rows where ripgrep is faster per search never pay off, and say so.
Do Scout and ripgrep find the same things?
A speed comparison is worth nothing if the two tools return different results. Before timing anything, every shared search was run through both and the matching lines compared.
| Search | Result |
|---|---|
| Literal, common | Same total — 165,315 matches counted by both, on 165,310 lines |
| Literal, rare | Identical — 33 matching lines in both |
| Regex | Identical — 774 matching lines in both |
| Word boundary | Same total — 11,073 matches counted by both, on 10,965 lines |
| Case-insensitive literal | Identical — 3,181 matching lines in both |
Environment
- Machine: AMD Ryzen 9 9955HX 16-Core Processor, 32 logical cores, 62 GB RAM, Windows_NT 10.0.26200.
- Versions: scout 2.1.0, ripgrep 15.2.0 (rev e89fff89ac), grep (GNU grep) 3.0, Node v24.19.0.
- Scout flags:
--no-semantic --no-telemetryfor the comparison battery,--semantic --no-telemetryfor the semantic rows. Find budget 120000 ms, page size 200. - Repository: dotnet/runtime v9.0.0 (59,319 files).
- Measured: 2026-08-23 on scout 2.1.0. The semantic rows and the semantic setup cost are carried over from 2026-08-22 on scout 2.0.0 — that tier is untouched by the changes the rest was re-measured for.
Raw results
The fine print
- Scout was faster than ripgrep on every text search here — 5 of 5, by 1.9–2.2x.
- The very first search in a new repository is slow, because the index has to be built first. The warm measurements exclude that setup cost.
- Fuzzy and semantic search return the best matches, not every match. Check coverage and completion for text, structural, and symbol searches; unsupported languages and limits can leave files unexamined.
- Not measured yet: how fast the index updates after edits, how speed scales with repository size, and how good the ranked results are.