diff --git a/docs/SCALING.md b/docs/SCALING.md index 681c54b5..4b108b99 100644 --- a/docs/SCALING.md +++ b/docs/SCALING.md @@ -39,6 +39,48 @@ The three knobs that matter most: The native vector provider (via the optional `@soulcraft/cortex` package) extends this with a higher-performing index — and its own at-scale acceleration such as on-disk compressed indexing — when installed. +## Measured Performance + +Numbers below are **measured** by `tests/benchmarks/find-composition-scale.js` (a single +Node 22 process, in-memory storage, 384-dim vectors, `balanced` recall). They are the +open-core (pure-TypeScript) path — what you get from `@soulcraft/brainy` with no native +provider installed. Run it yourself: `node --max-old-space-size=8192 tests/benchmarks/find-composition-scale.js 100000`. + +`find()` query latency, p50 / p95 (200 queries each): + +| Query | 5,000 entities | 100,000 entities | +|---|---|---| +| Vector similarity (`{ vector }`) | 0.8 / 1.3 ms | 1.4 / 4.7 ms | +| Graph 1-hop (`{ connected }`) | 0.5 / 0.7 ms | 0.7 / 0.8 ms | +| Metadata filter (`{ where }`, low-selectivity) | 0.7 / 1.2 ms | 23.5 / 30.1 ms | +| Vector + metadata | 7.7 / 8.3 ms | 78.8 / 93.8 ms | + +What the shape tells you: + +- **Vector and graph lookups scale ~logarithmically** — they barely move from 5k to 100k, + because HNSW search is ~O(ef·log n) and graph adjacency is O(degree). +- **Metadata-filtered paths scale with the size of the match set, not the database.** The + benchmark's `category` filter matches ~10% of rows (10,000 at 100k); the cost is + materializing that candidate set and running the vector search *inside* it (`find()` does + metadata-first hard filtering, then ranks within the candidates — see + [How find works](./FIND_SYSTEM.md)). A **high-selectivity** filter (few matches) is far + cheaper; a 10%-of-everything filter is the worst case. This candidate-restricted search is + precisely the path the native provider accelerates (Rust roaring-bitmap candidate + intersection). +- **Composition is correct, not lossy.** Combining vector + metadata + graph returns exactly + the entities satisfying all constraints — verified by + `tests/integration/find-triple-composition.test.ts`. + +Memory: ~62 KB resident per entity at 100k (6.2 GB RSS for 100k × 384-dim including the HNSW +graph, metadata index, and 100k edges). + +**Scale ceiling (open-core).** The pure-JS HNSW *build* cost (~100 inserts/s at 384-dim on +one core) makes the in-process open-core path most appropriate up to ~10⁵–10⁶ entities. +*Query* latency stays low well beyond that, but for the 10⁸–10¹⁰ regime install the native +provider (`@soulcraft/cortex`, on-disk DiskANN) — same API, no code change. _Projected from +the two measured points, vector p50 at 1M is ~2 ms; metadata-heavy composition grows with +match-set size and is the path to move onto the native provider first._ + ## Storage Configurations ### Filesystem (Recommended for Production)