Benchmarks · not cherry-picked

CodeMesh vs. reading the files yourself — a 100-question benchmark

The same 100 real developer questions, answered two ways: an agent reading the source files it would normally reach for, versus one query against the live CodeMesh graph over the same path the MCP connector uses. Every number on this page is measured from a real run, not modeled.

DATE 2026-07-20CORPUS 74,680 graph nodes · 7 languages · a real multi-service monorepoPRICED AT Claude Sonnet 5
91%
Median token reduction
11.6× fewer tokens, typical case · even the worst quartile (p25) is 6.5× (85% fewer) across 93 real questions
381,992
Tokens saved, this run
408,16326,171 tokens across the 93-question core set
$0.76
Cost saved, this run
At the Claude Sonnet 5 intro rate, $2/MTok input · projected $82/month saved at 10,000 queries
1.0 ms
Graph query, median
p90 73 ms · max 641 ms · zero errors across all 100 queries
2.810.8 ms
Reading files instead (shell)
cat one file: 2.8 ms · repo-wide grep: 10.8 ms — the graph is now faster than both
98/100
Answers under 500 ms
The remaining 2 wait on typed call-graph edges this project hasn't materialized yet (629–641 ms) — see §Engineering

How to read this

Nothing flattering was quietly dropped

A benchmark is easy to make look better than reality by discarding the questions that don't flatter it. Four categories showed up here that a cherry-picked benchmark would have dropped — they're kept in the full table below, and explained here instead.

93 CORE COMPARISONSOrdinary “what does this do / where is this / who calls this” questions. CodeMesh wins on tokens in essentially every one — median 11.6×, worst case still 6.5× at the 25th percentile.
1 OUTLIER, KEPT“Which issues mention sync?” has no file to grep — that data only exists via a connector. The file-reading method degenerates to scanning ~1M tokens of unrelated docs. Real result, not a representative one.
4: NO GRAPH ADVANTAGEPure counts (“how many files exist”) are already near-free with one shell command. The graph's JSON envelope made these slightly more expensive, not less. The graph wins on navigation, not on trivial counting.
2: SERVER-SIDE TIMEOUTQueries with an unbound relationship target initially timed out entirely (>562 s measured). Root-caused to an O(degree) read pattern and fixed in the engine — they now run in 218–447 ms.

Distribution

How often is it 100×, not just 11×?

The median undersells the tail. 93 core comparisons, bucketed by how many times cheaper the graph answer was than reading the source file(s).

Token-reduction multiple, by question
93 core comparisons
<5x
15 questions
5–10x
25 questions
10–25x
32 questions
25–100x
13 questions
100–500x
7 questions
500x+
1 question

Speed

The graph is now faster than the method it replaces

Measured across the full 100-query battery: median 1.0 ms, p90 73 ms, 98/100 under 500 ms, zero errors. Compared the way tools are actually invoked, a graph round trip (including the HTTP hop) now beats the practical fallback: spawning cat on one file costs 2.8 ms and a repo-wide grep costs 10.8 ms (medians of 20+ runs each). Only a bare in-process file read (0.02–0.2 ms — a raw syscall no agent performs in isolation) beats it.

Median latency by method
Lower is better · log-scaled bar widths
CodeMesh graph query
1 ms
cat (one file)
2.8 ms
grep (whole repo)
10.8 ms

Engineering

How the engine got this fast

This benchmark surfaced three real bottlenecks in the graph engine mid-run. They were root-caused and fixed in the same session, then the full battery was re-run for the numbers above. These are before/after measurements of our own engine, not a comparison against any other product — shown here for the same reason the outlier and no-advantage questions are: nothing flattering gets quietly dropped.

1 · Planner anchor orientation
10,235 ms79 ms

The query planner always anchored on the first pattern node, scanning the entire graph to answer “what's in this file.” It now scores both ends of a query pattern and anchors on whichever is more selective — cost becomes proportional to the answer, not the size of the graph.

2 · Ranked seek keys + indexes
79 ms1 ms

Seek-key selection took the first filter condition instead of the most selective one. Every condition is now ranked by index selectivity before the engine picks which one to seek on.

3 · O(degree) point reads
562 s410 ms

Reading one node was decoding its entire adjacency list every time — tens of thousands of entries per read against a well-connected node. A stub-free read path restores the invariant that reading a node never costs more as the graph grows around it.

Two questions still land over 500 ms: “who calls X” today runs a scan over an array property across ~32,000 function nodes (629–641 ms) — inherently proportional to that array, no index helps it. The durable fix is materializing typed call edges at ingest time, which turns this into a ~1 ms edge walk; that work is scheduled, not yet shipped for this project.

Verified with new engine regression tests plus the full existing test suite — all green, and every benchmark answer is byte-identical to the pre-fix run.

All 100 questions

The complete, unfiltered result set

Click a column header to sort. “Reading files” tokens are the actual byte count of the file(s) an agent would read, ÷4. “CodeMesh” tokens are the actual JSON response from the live graph query, ÷4.

#QuestionReading filesCodeMeshReductionLatency (pre-fix)Latency (now)
1What does the OAuth server in the gateway do?2,0104104.9×10.5 s14.8 ms
2What's implemented in the JWT signing code?9841905.2×10.4 s1.4 ms
3What does the code-sync bootstrap module implement?2,69622811.8×10.4 s1.4 ms
4What does the query guard do?1,98718610.7×10.4 s1.2 ms
5What's in the policy engine?1,3082994.4×10.4 s1.4 ms
6What does the quota module do?55718610.7 s1.0 ms
7What does the audit module do?9802034.8×10.7 s1.0 ms
8How does project mode (auto vs manual) work?5341832.9×10.7 s0.9 ms
9What does the gateway's main.go set up at startup?3,97322417.7×10.6 s1.0 ms
10How does the OpenMetadata connector sync work?5,96343113.8×9.8 s1.4 ms
11How does the extraction engine parse a repo?4,1646076.9×10.3 s1.7 ms
12How does per-file extraction work?3,30830011×10.2 s1.1 ms
13How are languages mapped to parser grammars?1,1791926.1×10.2 s0.9 ms
14How are graph elements emitted for ingestion?2,3152499.3×10.2 s1.2 ms
15What's the manifest format used for skip detection?5491673.3×10.6 s0.8 ms
16What does the sync daemon's CLI entry point do?4,65541811.1×10.6 s1.1 ms
17How does the sync daemon work?2,8803059.4×10.7 s1.0 ms
18How does a sync job run end to end?1,1218113.8×10.2 s0.9 ms
19How does the pusher decide fast-lane vs bulk?3,29225612.9×10.3 s1.0 ms
20How does the file watcher work in the sync daemon?8941048.6×10.5 s0.7 ms
21How is daemon config loaded?1,41228410.6 s0.9 ms
22How does the sync daemon track git branch/commit state?4221034.1×10.6 s0.8 ms
23What do the agent hooks in the sync daemon do?556609.3×10.3 s0.7 ms
24How does connecting an agent to the sync daemon work?3,23830210.7×10.2 s1.2 ms
25What does the supervise command do?2,3292638.9×10.3 s1.0 ms
26What does the VS Code extension's main file do?3,94031112.7×10.2 s0.9 ms
27What's in the VS Code sidebar view?2,0233056.6×10.0 s2.1 ms
28What does the connector CLI do?7975913.5×10.4 s0.8 ms
29How does the connector CLI's core logic work?2,8373408.3×10.3 s0.9 ms
30What does the Cursor SDK helper do?7956412.4×10.2 s0.5 ms
31What does the ingestion service's main.go start up?18,91336851.4×10.0 s1.4 ms
32What does the raw query endpoint do?1,6179018×10.1 s0.7 ms
33What's in the graph intelligence activities file?56,7452,47422.9×5.1 s3.2 ms
34What do the proactive agent handlers do?30,8242,22813.8×10.1 s3.2 ms
35What do the ingestion Temporal workflows do?27,80070939.2×9.9 s1.4 ms
36What do the connector sync activities do?27,2601,53817.7×10.0 s2.2 ms
37What does the identity service's server.js set up?4984112.1×10.0 s0.6 ms
38What does the data service's main.py do?653719.2×10.0 s0.7 ms
39What does the analytics service's main.py do?9353924×10.2 s0.5 ms
40What does the MCP backend's main.py do?1,64411114.8×10.3 s0.6 ms
41What is the graph engine positioned as, per its README?4,85018269.4×10.3 s0.8 ms
42What's the storage abstraction interface in the graph engine?1,26910112.6×10.4 s0.8 ms
43How does the graph engine's Bolt server work?1,0462414.3×10.3 s1.0 ms
44How does vectorized query planning work in the graph engine?3,63918120.1×10.4 s0.7 ms
45How does the query planner choose a seek key?6,4747009.2×10.4 s1.4 ms
46How does transaction management work in the graph engine?6871863.7×10.4 s0.8 ms
47How does conflict retry work in the graph engine's transactions?325635.2×10.4 s0.6 ms
48How does full-text search work in the graph engine?1,8703275.7×10.4 s1.0 ms
49How is the fulltext index built in the graph engine?2,1603386.4×10.4 s1.1 ms
50How does the BadgerDB storage backend work?8,1541,2566.5×10.3 s2.4 ms
51How does the MongoDB storage backend work?3,1713469.2×10.4 s1.0 ms
52How does bulk writing work on the Mongo backend?2,42020811.6×10.3 s0.7 ms
53How does the graph engine's built-in MCP server work?1,89821210.3 s0.8 ms
54How does RBAC/auth work in the graph engine?4491273.5×10.4 s0.9 ms
55How does the bulk ingest pipeline work in the graph engine?6926111.3×10.3 s1.7 ms
56How does the bulk loader work in the graph engine?1,1742983.9×10.4 s0.9 ms
57What's documented in the graph engine's architecture doc?7871843.7×10.4 s0.9 ms
58What's documented about the graph engine's Cypher compatibility?7821843.4×10.2 s0.5 ms
59What does the graph engine's main entry point do?5,21932616×10.4 s1.1 ms
60Compare the graph engine's Badger and Mongo storage backends.11,3251,25610.3 s2.0 ms
61Where is MintBootstrap defined and what does it call?2,01011817×517 ms1.0 ms
62Who calls SignHS256?9842284.3×717 ms640.6 ms
63Where is handleCodeSyncBootstrap implemented?2,69619813.6×525 ms2.6 ms
64What does handleCodeSyncGitHubWebhook do?2,69614219×532 ms1.4 ms
65Where is JoinScope defined?9844024.6×510 ms1.0 ms
66Where is randomID defined and who uses it?9841277.7×702 ms628.6 ms
67Where is run_sync implemented in the sync daemon?1,1211736.5×561 ms1.1 ms
68Where is extract_repo defined in the extraction engine?4,16412832.5×523 ms2.0 ms
69Where is the seek-key ranking function implemented in the graph engine?6,47419340.7×510 ms1.5 ms
70Where is the merge seek-key chooser defined in the graph engine?6,47462104.4×525 ms0.7 ms
71Where is the endpoint-seek chooser defined in the graph engine?3,63919191.5×520 ms0.6 ms
72Where is is_passthrough defined in the extraction engine?1,1793831×514 ms0.7 ms
73Where is the connect function for agent hooks defined?3,2383708.8×422 ms0.8 ms
74Where is autoConnectSync implemented in the connector CLI?2,8377239.4×520 ms0.7 ms
75Where is forwardMcpStdio implemented?2,83713421.2×530 ms0.6 ms
76How many files does the codebase graph track for this project?no advantage2170.1×79 ms72.9 ms
77How many functions are there in the codebase, broken down conceptually by size?no advantage018524 ms461.5 ms
78Which open Linear issues mention sync?outlier1,016,7422274,479×106 ms92.2 ms
79What GitHub repositories are tracked in the ontology?14,48418080.5×4 ms2.9 ms
80Which files in the codebase are the biggest by lines of code?961930.5×105 ms83.9 ms
81How many CodeImport nodes exist and what does that represent?1,5491886.1×369 ms354.3 ms
82What's the breakdown of files by language in this codebase?no advantage11800.1×79 ms75.6 ms
83How many CodeClass nodes are there in this project?no advantage017129 ms153.6 ms
84What connector is the codebase ingested through?fixed2,1436>562 s446.6 ms
85Which repository is this project's code attached to in the graph?fixed266>562 s218.1 ms
86What does the decisions log record?1,5681887.1×9.5 s1.4 ms
87What's documented in the MCP connection guide?2,16018120×9.5 s0.7 ms
88What does the API gateway's README describe?1,7851899.2×9.6 s0.6 ms
89What does the OAuth bootstrap test cover?246445.6×9.7 s0.7 ms
90What does the code-sync bootstrap test cover?219653.4×10.0 s0.8 ms
91What does the gateway's integration test cover?9,4839649.8×10.1 s1.6 ms
92What does the auto-connect e2e test check?8601847.8×10.2 s0.6 ms
93What does the sync-connect setup script do?6051833.6×10.1 s0.6 ms
94What does the ops script manage?13,14918730.5×10.0 s0.6 ms
95What ports and services does the environment config define?7,08818393.8×10.0 s0.5 ms
96How do the OAuth module and code-sync bootstrap module interact?4,70541011.5×10.1 s1.1 ms
97Compare the sync daemon and its sync-job module.4,00030513.1×10.1 s1.0 ms
98Compare the graph engine's architecture doc with its README.5,63618313.1×10.3 s0.6 ms
99Compare the VS Code extension and the connector CLI as MCP entry points.6,77731021.9×10.0 s1.0 ms
100Compare the API gateway's OAuth flow with the graph engine's RBAC auth.2,45841010.2 s0.9 ms

Accuracy

Verified against real source, not assumed

Token and latency numbers say nothing about whether the graph's answer is actually correct. A sample of results was cross-checked against independently-derived ground truth — real regex extraction from source, real grep for call sites, real shell counts — rather than trusting the graph's output at face value.

100%
Symbol listings
54/54 verified exact against real source, once corrected for test artifacts
100%
Reverse caller lookups
Every real call site correctly attributed (2 targets, 15 real sites)
8/9
Forward call resolution
1 inconclusive due to an unscoped test query, not a confirmed graph error
100%
Aggregate counts
5/5 — file count within 0.6% of a real filesystem count, an explainable scope difference

10 raw “mismatches,” all traced to root cause — none were graph errors.

3 (graph-engine files): the “missing” symbols were checked against the canonical, up-to-date engine repo — but the graph had ingested a clone two commits behind. Confirmed directly: those symbols don't exist in the clone that was actually synced. The graph was 100% correct relative to its real source.
7 (TypeScript/JS files): the ground-truth regex over-counted local constvariables as symbols and missed bare class methods without a function keyword — a limitation of the test harness, not a graph defect. Reclassified as inconclusive rather than scored either way.
3 of 4 call-graph “mismatches” were also test artifacts: the ground-truth check only grepped the first 2,000 characters of each function body. Reading the full bodies confirmed the flagged calls really do happen — just past where the truncated check stopped looking.
The one real, standing accuracy gap: a generic, commonly-named callee resolved to an unrelated function of the same name in a different service. The batch check only verifies a name was called somewhere in the body — not whether the graph's claimed definition location for a generic name is the right one (here, it wasn't). This affects generic/common callee names resolved via unscoped cross-service matching — not symbol listings, not counts, not reverse lookups, not distinctively-named callees.

Cost

Priced at real Claude Sonnet 5 rates

These tokens are context returned into the model — i.e. input tokens on the model's next turn — priced at published per-million-token rates.

Pricing tierReading filesCodeMeshSaved
Intro — $2.00/MTok (through 2026-08-31)$0.8163$0.0523$0.764
Standard — $3.00/MTok$1.2245$0.0785$1.146
All 98 completed queries, intro rate$2.8498$0.0531$2.7968

Addendum · one real incident

A schema-ambiguity edge case, found and fixed

Separate from the 100-query sweep above — this is a single real scenario, kept to its actual scale (not inflated into 100 cases). It matters because it shows token reduction and answer correctness are different axes, and this is the clearest example of them pulling in opposite directions.

Asked “what connectors are in the data service,” the graph first matched a small set of this project's configured integrations — when the real answer was a much larger internal plugin catalog that only exists as source files, not as connector records. Nothing distinguished the two meanings before the agent queried. Fix: the query-guidance tool now surfaces a disambiguation note whenever that ambiguity is possible, and shows both query shapes side by side. Verified with unit tests plus one live end-to-end run against the real code path.

Before fixAfter fixGround truth
Accuracy0% — answered a different question100% (91/91)100% (ground truth)
Round-trip time21 ms165 ms26 ms
Response tokens30120232
Cost / 10,000 queries$0.6$2.4$4.64

Fixing correctness cost time and tokens here — it didn't save them. The old query was fast only because it skipped the guidance step straight into a wrong answer. The corrected graph path still beats reading files on tokens (120 vs. 232 — 48% fewer) despite the added guidance overhead. Treat this as one worked example of the tradeoff, not a generalizable rate.

See it on your own repository

These numbers are from one real monorepo. The fastest way to know what CodeMesh does for yours is to open one.