# I indexed a 96k-file Linux kernel tree in 2m51s on a laptop — benchmarking two code-graph MCP servers

> Source: <https://dev.to/ysenthilvasan/i-indexed-a-96k-file-linux-kernel-tree-in-2m51s-on-a-laptop-benchmarking-two-code-graph-mcp-lmg>
> Published: 2026-10-24 19:36:33+00:00

**Disclosure up front: I'm the author of [SMP (Structural Memory Protocol)](https://github.com/offx-zinth/SMP)** — an open-source (MIT) MCP server that keeps a live structural code graph. This post is the full methodology and numbers; everything below is reproducible.

Coding agents can read files. What they mostly can't do is answer *structural* questions: who calls this, what breaks if I change it, which tests cover it. Grep gives you matches, not a map. Embedding-based RAG finds "similar" code, rarely "connected" code. So SMP maintains a graph: tree-sitter parses each file into nodes (functions, classes, modules) and edges (calls, contains, imports), stored in a **single memory-mapped file with a journaled write-ahead log** — no Postgres, no Neo4j, no embeddings.

Every number below was measured on the same laptop: an 8-thread 11th-gen Intel i7-1165G7, 14 GB RAM, NVMe, Linux, no GPU. Both tools did a fresh full index of the identical directory tree. No vendor numbers are mixed in.

| Corpus | SMP | codebase-memory-mcp (fast mode) | 
|---|---|---|
| Linux kernel snapshot — 95,937 files (72,171 parsed) | **2 min 51 s** — 839,516 nodes, 4,066,943 edges, 2.2 GB graph, 6.5 GB peak RAM | **13 min 14 s** — 4.8 GB index | 

**4.6× faster on the same hardware, same tree.** One caveat: codebase-memory-mcp excluded 36 directories by design (gitignored/vendor paths), so node counts describe different graph models — wall-clock on the same input is the comparison.

| Corpus | SMP | codebase-memory-mcp | 
|---|---|---|
| 208-file Python repo | **0.99 s** — 4,575 nodes / 18,862 edges | **5.27 s** — 4,346 nodes / 22,002 edges | 

Micro-benchmark (`benchmarks/benchmark_scale.py --nodes 60000 --depth 3`), synthetic graph, no MCP overhead:

This is my favorite part. `locate` used to **re-load every node and re-tokenize the entire BM25 corpus on every query** — 1,493 ms p50 on a 4,575-node graph. On the 839k-node kernel graph it OOM-killed my desktop twice (systemd-oomd took out the whole session).

The fix: a monotonic **store revision counter** plus an engine-side corpus cache (≤250k nodes; larger graphs fall back to the original path). Results are **byte-identical** to the pre-fix code, covered by 9 new equivalence/invalidation tests — and `locate` dropped to **40–85 ms p50 (~15–37× faster)**.

Other MCP tools on a warm 4,575-node graph: `smp_context` p50 29.9 ms, `smp_file_outline` p50 9.3 ms.

One line wires the MCP server + agent skill into Claude Code, OpenCode, Codex or Cursor:

```
curl -fsSL https://raw.githubusercontent.com/offx-zinth/SMP/main/install.sh | bash
```

Repo (MIT, benchmark scripts included so you can re-run every table above on your own hardware): [https://github.com/offx-zinth/SMP](https://github.com/offx-zinth/SMP)

Incremental re-index on partial edits at >500k nodes; monorepo-scale retrieval without vectors; Apple Silicon timing runs. If you run agents on a large repo, I genuinely want to know where it breaks for you.
