Fuse
Project

Performance and latency

Measured cold start, warm read latency, and verify-path timing for Fuse, sourced from the recorded benchmark result files.

Fuse builds the persistent index once and reads it warm across calls. This page publishes archived measurements from tests/benchmarks/results. Fuse 4.4 does not ship fuse eval, fuse resident-latency, or fuse testexec; their source and recorded output remain in the separate Fuse.Benchmarks.slnx solution. Timings are environment-dependent; read them as within-environment SLOs, not cross-machine guarantees.

Warm persistent index

Fuse analyzes each source file and stores the result in a persistent SQLite database at .fuse/fuse.db (WAL mode). The MCP server (fuse mcp serve) and the host process reuse that store, so scoped calls do not re-parse unchanged files. Single-file incremental re-index clears and re-extracts only the changed file's syntax rows; it does not recompute cross-file semantic edges, which a full re-index refreshes.

One-shot CLI commands pay startup cost on every invocation. A long-running server pays it once per session; warm latencies below apply after that first pass. The separate live compilation workspace is opt-in with FUSE_RESIDENT=1. Cache key derivation and store layout are in Caching Internals.

Warm read verbs (two scales)

Each verb is the primitive the matching MCP tool calls, timed over 25 iterations at two scales: NodaTime (512 files, 14,760 symbols, semantic tier, performance.json) and eShopOnWeb (287 files, 2,216 symbols, partial semantic tier, performance-eshop.json).

Verb (tool)NodaTime P50NodaTime P95eShopOnWeb P50eShopOnWeb P95
Exact symbol lookup (fuse_find)1.8 ms2.3 ms0.2 ms0.3 ms
Blast radius (fuse_impact)~0 ms0.1 ms~0 ms~0 ms
Localize (fuse_find kind=task)15.7 ms22.3 ms2.3 ms2.9 ms
Resolve symbol (fuse_find kind=service)~0 ms0.1 ms~0 ms0.1 ms
Review plan (fuse_review)106.3 ms131.1 ms49.7 ms66.5 ms
Single-file incremental re-index22.0 ms24.2 ms1.9 ms2.2 ms

Every recorded warm read sits inside a sub-second budget on this machine. eShopOnWeb is faster in this run, but two repositories do not establish a proportional scaling law. Both checkouts now load a semantic graph (NodaTime via the product solution src/NodaTime.slnx, eShopOnWeb at partial tier), so fuse_impact walks real edges; it still reads ~0 ms because these neighborhoods are small, bounded by neighborhood size rather than by an empty graph.

Verify verbs (NodaTime, resident-latency.json)

fuse_check answers from a live resident workspace when one serves the root. This path is opt-in with FUSE_RESIDENT=1; the default store-backed path is not represented by these timings. The operations below were timed over 25 iterations against held compilations:

Verify operationP50P95Gate
Overlay check, analyzers off (speculative typecheck)31.2 ms42.4 msP95 < 1000 ms: PASS
Delta mode, whole-state diff203.9 ms699.3 msP95 < 1000 ms: PASS
Raw analyzer execution (284 analyzers)871.8 ms886.9 msInformational

The analyzer timing measures raw analyzer execution against the held compilation. It does not measure editorconfig severity mapping or establish full CI parity. The resident workspace warms once (build plus rehydrate) at about 14.1 seconds and holds the compilations at 162 MB RSS for the NodaTime checkout.

Test execution (testexec.json)

The build-grade covering-test runner (behind fuse_test) runs the selected covering subset through the real dotnet test:

OperationMedian
Covering-test run (build-grade, incremental)1,792 ms

The first run pays the full build; each subsequent incremental run (one file changed) is about 1.8 s. The sub-second emit fast-path (run the covering subset in-process against the emitted assembly, no build) is a named follow-up.

Cold start

Measured on NodaTime (performance.json) and eShopOnWeb (performance-eshop.json):

MilestoneNodaTimeeShopOnWeb
Syntax tier served (no MSBuild)17,768 ms1,349 ms
Semantic-ready (background upgrade)+71,052 ms+22,742 ms
Full synchronous semantic index (fuse index)45,859 ms10,718 ms

These are re-measured (2026-07-15) after the workspace-discovery fix, which selects the product solution src/NodaTime.slnx (21 projects, 14,760 symbols) rather than the auxiliary build/Tools.slnx (2 projects, 343 symbols); the prior snapshot indexed at the syntax tier and so understated the real semantic cold-index cost. The semantic pass loads via tier-1 build capture (graph-grade), which is why it is slower than the earlier syntax-only figure - it is doing strictly more (the full typed graph).

These measurements describe the pre-4.4 background-upgrade workflow. Fuse 4.4 serves a syntax index by default and does not start a workspace-wide compiler pass in the background. Use fuse index --semantic for an explicit compiler pass. No timing comparison is claimed for the changed workflow.

On the semantic path the chunk and route extraction share one parse per file with the compilation instead of re-parsing the content string (R47), so the cold-index parse count per file drops with byte-identical output - a reduction of raw work, never an increase. The per-project wiring-analyzer pass also runs concurrently across projects (R45): on eShopOnWeb (10 projects) it dropped from ~3.4s to ~0.75s with byte-identical nodes and edges (environment-dependent, recorded in the R45 progress log).

Tier-1 build capture (dotnet build then rehydrate from the log) is the higher-grade compiler path, not the faster one. The recorded pre-4.4 A/B on eShopOnWeb (10 projects, environment-dependent, recorded in the R49 progress log) cold-indexed capture-on at ~16.4s versus the tier-2 MSBuildWorkspace path at ~13.6-15.0s. In 4.4 capture is reserved for portable capture and compiler-backed verification; the default syntax job and fuse index --semantic do not build the workspace through the capture worker.

Warm Solution for refactor and doctor

fuse_refactor and fuse_workspace action=doctor's live load each need a design-time MSBuild workspace, and opening one is essentially their whole latency. The daemon holds the loaded Roslyn Solution per root and reuses it across calls (R42), so only the first call in a session pays the load. Measured on the Fuse repo through the refactor and diagnose engine (environment-dependent, recorded in the R42 progress log, not a canonical result file):

ToolFirst call (cold load)Warm reuse
fuse_refactor (rename)~23,700 ms~450 ms
fuse_workspace doctor (live load)~13,900 ms~870 ms

The held solution is memory-heavy (a full compilation set), so the cache is a hard LRU (FUSE_WARM_SOLUTION_CAP, default 3) with an idle window (FUSE_WARM_SOLUTION_IDLE_MINUTES, default 30); the held-solution RSS ceiling was about 594 MB at cap 3. A freshness check reloads when the source changed, so a reused solution matches a cold load exactly and a changed tree is never slower than before.

For the store-backed default (no resident workspace), fuse_check's oracle path keeps a pooled build-capture worker per captured compiler log (R48). R53 records source ownership first, then rehydrates only the captured C# project containing the requested file; later checks reuse that project and a request for a different project rehydrates only that project. The check still uses the same speculative fork and diagnostics path as a full-log rehydration, so verdicts remain identical and check honesty is preserved. Environment-dependent first-check measurements are recorded in the roadmap progress log.

Distribution

Fuse distributes as a framework-dependent .NET global tool and as self-contained runtime-specific packages:

PackageRole
FuseFramework-dependent dotnet tool with RollForward=LatestMajor (portable IL; no ReadyToRun, since a framework-dependent tool has no target RID to crossgen for)
Fuse.Runtime.win-x64 (and other RIDs)Self-contained binary for that runtime identifier, published ReadyToRun (crossgen) for a faster cold start
Windows installerShips the self-contained fuse.exe from the release workflow

Roslyn structural analysis is always included; there is no trimmed or regex-only binary.

The self-contained runtime binaries are published ReadyToRun (R50), so a one-shot runtime-binary CLI invocation pays less JIT warmup on cold start. Measured on win-x64 (fuse --version, environment-dependent): ReadyToRun ~150 ms versus ~188 ms without it (best 146 vs 181 ms). The configured ambient hooks use the framework-dependent fuse tool, so each event still starts that command even though it asks the warm daemon for diagnostics. R57 measured Release fuse check --delta --fast at 155 to 171 ms with no host and 239 to 294 ms with a serving host; the latter includes process startup plus the pipe round trip. Full AOT is not used (its native link is unavailable in the build environment); the long-lived daemon pays JIT once per session and is unaffected either way.

Recorded-result maintenance

Benchmark source, corpus manifests, and recorded result files live outside the product solution in Fuse.Benchmarks.slnx. The packaged tool has no evaluation command, and ordinary release validation does not execute the benchmark harness. profile-v42.json records SQL and Roslyn frame attribution on the warm index path (WorkspaceIndexStore, SemanticIndexer) for store-split planning. It is maintainer evidence for R8/R9, not a published latency SLO; compare wall-clock numbers to performance.json for the same verbs.

Token efficiency (median tokens a review returns) is on Benchmarks. Test-selection latency is the covering-tests query inside fuse_impact; a standalone timer for it is follow-up work.

Next

Read Benchmarks for recall and token suites, Caching Internals for store reuse, or Pipeline for the stages behind a fusion.

On this page