BrowserVec vs. hnswlib-wasm vs. Vectorious (BLAS brute force) vs. naive JS brute force —
latency, recall, memory, and ingest speed, all running live in this tab on synthetic clustered vectors.
Recall is measured against the naive JS brute force engine's results, since it's
an exact (not approximate) scan — same reference the other engines are checked against. BrowserVec's
default flat index is also exact, so it should track ~100% recall; the quantized BrowserVec rows and
hnswlib-wasm are approximate — quant recall depends on the code width + exact re-rank, HNSW recall on
efSearch (and the efConstruction/M build parameters).
efSearch is clamped to ≥ k; hnswlib's own default (~10) is below k=20 and craters recall.
Memory is a computed bytes-per-row estimate of the scan corpus each engine reads per query
(fp32 vectors, packed quant codes + scales, or vectors + a rough graph-overhead term for hnswlib-wasm),
not a measured heap snapshot — WASM/JS heap introspection isn't reliable across browsers. BrowserVec's
quantized modes also keep an fp32 copy CPU-side for the exact re-rank and persistence, like every
engine here keeps its source data.
Time breakdown: for BrowserVec, GPU is the measured wait on submitted GPU
work (kernel execution + queue scheduling), Transfer is a separately measured
readback/map round-trip cost on the same device (fixed sync overhead — the score readback itself is
small), and CPU is everything else (prep, candidate gather, exact re-rank, top-k merge).
"GPU busy" is the fraction of query wall time spent waiting on the GPU — browsers expose no true
hardware-utilization counter, so treat it as attribution, not occupancy. WASM/JS engines are 100% CPU.
Why no usearch or faiss? Neither ships a browser build on npm — usearch
and faiss-node are native Node.js addons (node-gyp/NAPI), so they can't run in a web page.
The WASM engines that do run in-browser are represented by hnswlib-wasm and voy-search (Rust→WASM
kd-tree), plus Orama as a pure-JS vector search. voy-search is skipped on very large corpus×dim
configurations — its JSON-based ingest is not built for that scale.