Round-3 perf push sub-issue (tracked under umbrella #536).
[L] No async / mmap-page prefetch for cold-cache HNSW graph
- Where: HNSW reader uses
OnDemand for Lazy storage (hnsw/reader.rs:260-313) but
OnDemand::get does serial seek + read_exact (storage.rs:209-251). The HNSW search
hot path falls back to get_vector for any non-Eager storage
(hnsw/searcher.rs:586-595).
- Current behavior: In Lazy mode every neighbour load is a blocking seek+read. No
page-cache warmup, no madvise(MADV_WILLNEED), no batched read.
- Why it might be a bottleneck / risk: Indexes that don't fit in RAM run at disk-latency
× ef_search × neighbours.
- Reference precedent: DiskANN / Vamana beam-search batches I/O for
BeamWidth
candidates in flight; LanceDB IVF_PQ uses tokio::io::AsyncReadExt for cold scans.
- Suggested direction: (1)
mmap() .hnsw in Lazy mode and madvise regions
containing int8 payload. (2) Switch OnDemand::get to read N records in one syscall.
(3) Beam-search variant of search_graph that holds BeamWidth candidates pending I/O.
- Risk / scope: Large. Dramatic win for disk-resident corpora.
ID: VS-20 — see ~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.md for the full Round-3 issue list.
Round-3 perf push sub-issue (tracked under umbrella #536).
[L] No async / mmap-page prefetch for cold-cache HNSW graph
OnDemandfor Lazy storage (hnsw/reader.rs:260-313) butOnDemand::getdoes serial seek +read_exact(storage.rs:209-251). The HNSW searchhot path falls back to
get_vectorfor any non-Eager storage(
hnsw/searcher.rs:586-595).page-cache warmup, no
madvise(MADV_WILLNEED), no batched read.× ef_search × neighbours.
BeamWidthcandidates in flight; LanceDB IVF_PQ uses
tokio::io::AsyncReadExtfor cold scans.mmap().hnswin Lazy mode andmadviseregionscontaining int8 payload. (2) Switch
OnDemand::getto read N records in one syscall.(3) Beam-search variant of
search_graphthat holdsBeamWidthcandidates pending I/O.ID:
VS-20— see~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.mdfor the full Round-3 issue list.