CPU retrieval performance
examples/performance.rs builds an explicitly synthetic SQLite corpus using the
real core schema and normal FTS triggers. It measures warm core retrieval only;
there is no filesystem scanning, document extraction, model inference, GUI
rendering, or GPU provider in this benchmark.
The default smoke fixture contains 10,000 file records and 1,000 searchable document/passages. The acceptance fixture contains 1,000,000 file records and 100,000 searchable documents, one paragraph per document. The remaining records have filenames but no content. Names and documents are synthetic; they do not represent a realistic corpus distribution, so passing these measurements alone would not establish production performance.
cargo run --release -p searchi-core --example performance -- --files 1000000 --documents 100000 --samples 20 --db target/benchmarks/full.db
Use a new database path when seeding. The harness refuses to overwrite an
existing database. To compare engine versions on the same corpus, use --reuse true;
this validates file/document counts and synthetic root ownership before opening
and migrating the existing fixture. It records migration time separately and
reports zero seed time. It seeds at most 5,000 records per transaction, checkpoints
the WAL, then performs three warmups and 20 measured queries per case. Percentiles
use the nearest-rank convention; with 20 samples, p95 is the 19th sorted sample.
The first execution of each query is recorded separately before the remaining
two warmups; this is first use of that query on the current engine, not a cold
OS disk-cache test. Timing uses a monotonic clock. Results include committed database size and fixture
seed time, which must not be described as document extraction throughput.
Cases cover an exact filename near the end of the corpus, a broad filename substring, a unique content token, and a broad content token. All queries use the public search API with limit 20, including actual source-passage selection. Target p95 is below 50 ms for filenames and below 150 ms for keyword search. A result above either target is explicitly marked as a failure. Database file bytes exclude temporary WAL/SHM sidecars and process memory.
Reference environment
- Date: 2026-10-12.
- Windows VM: Windows 11 Pro, version 10.0.26300.
- CPU name exposed by VM: AMD Ryzen 7 7800X3D 8-Core Processor.
- VM allocation: 4 logical processors, 10,666,553,344 bytes RAM (about 9.93 GiB).
- Rust release build, bundled SQLite, CPU only.
- Toolchain: rustc 1.99.0 (b940084d7 2026-09-28), cargo 1.99.0.
- Engine baseline:
a9b6592330d88745eadf2a748bb3a65f62830590, schema 4. - Storage device and host scheduling contention are not characterized.
Run results are stored in results/. Linux and macOS measurements are pending.
No cross-platform acceptance claim can be inferred from the Windows VM results.
Baseline result
The full acceptance fixture fails all four latency targets. This is a verified performance gap, not a production-ready retrieval result.
| Query case | p50 | p95 | p95 target | Result |
|---|---|---|---|---|
| Exact filename | 404.76 ms | 633.82 ms | <50 ms | Failed |
| Broad filename substring | 3,385.76 ms | 4,131.48 ms | <50 ms | Failed |
| Unique content token | 311.63 ms | 355.78 ms | <150 ms | Failed |
| Broad keyword | 2,186.24 ms | 2,746.91 ms | <150 ms | Failed |
The 1M/100K synthetic fixture took 277.23 seconds to seed and its checkpointed database occupies 309,338,112 bytes (about 295 MiB). Smaller 10K/1K smoke results passed the same targets, showing why small-corpus tests must not be used as proof of scalability. Neither seed time measures document extraction throughput.
The baseline implementation scanned file metadata for substring matching and used per-result passage lookups. Its measured behavior warranted a dedicated filename substring index, candidate-first FTS retrieval, and batched passage selection. The following section records the resulting implementation and measurements.
Optimized result, schema 7
The unchanged full fixture was migrated and reused. All four warm target measurements pass in this Windows CPU run. This does not establish production acceptance for all workloads or operating systems.
| Query case | Baseline p95 | Optimized p50 | Optimized p95 | First use | Warm target |
|---|---|---|---|---|---|
| Exact filename | 633.82 ms | 11.66 ms | 13.17 ms | 279.73 ms | Passed |
| Broad filename substring | 4,131.48 ms | 0.39 ms | 1.68 ms | 3.34 ms | Passed |
| Unique content token | 355.78 ms | 0.28 ms | 0.39 ms | 50.08 ms | Passed |
| Broad keyword | 2,746.91 ms | 97.92 ms | 111.54 ms | 101.35 ms | Passed |
The updated checkpointed database is 634,449,920 bytes (about 605 MiB). The
improvement trades additional indexes and disk space for retrieval latency.
The initial schema-4-to-5 backfill took 19.65 seconds on this fixture, as recorded
in the intermediate report. The final report's 3.84 ms migration_seconds is an
already-current-schema open, not a measurement of the initial index backfill.
Indexed equality, trigram candidate retrieval, content-only FTS, and a single
batched source lookup replaced full metadata joins and per-result FTS scans.
Rarest-trigram vocabulary counts are cached in the reader engine. The first-use
exact result exceeds the warm target and is explicitly retained as an outstanding
latency issue; opening a fresh reader for every query discards this cache.
windows-cpu-full-optimized-v7.json is the final measurement. Earlier schema 5/6
reports are intermediate experiments and retain failed exact-query measurements.
The final run did not overlap another benchmark process. Dedicated host isolation
is still not established. Query distribution and filters are not represented by
this four-case fixture; restrictive broad filters and sub-three-character searches
remain potentially slow, while correctness tests ensure late matching files are
not lost through arbitrary pre-filter caps.