Benchmarks

Every number here comes from a committed script you can rerun — with relevance checked against Lucene and Tantivy oracles.

All figures below were measured on a 14-core laptop with the benchmark scripts committed in the repository (scripts/*_bench*.mjs, npm run bench:*); cold numbers reset every cache first. Corpora are public so you can reproduce end to end.

Build

Corpus Documents Build time Index size Peak RSS
French Wikipedia 2,753,081 ~10.5 min 5.3 GB 4.7 GiB
English Wikipedia 7,194,531 ~52 min ~9 GB 6.1 GiB
OSM Québec 6,095,740 ~7 min 9.5 GB
OSM United States 32,809,763 ~27 min 11 GB

The builder is file-backed throughout — postings spill to bounded segments and merge in tiers — so memory stays flat as corpora grow, and every phase checkpoints for resumable builds.

Query — text (English Wikipedia, 7.2M pages, cold)

Query shape Latency Transfer
single term 7–66 ms tens–hundreds of KB
United States (two high-frequency terms) 128 ms 2.3 MiB
autocomplete prefix (mach) 49 ms 417 KB

Early termination is what makes the two-word case work: exact evaluation of that query would read ~13 s of postings; impact-ordered blocks with a block budget reach the same top-10 105× faster.

Query — geo (OpenStreetMap, cold)

Corpus Points Nearest (cold) Warm
Québec 6.1M 5–13 ms 0.1–0.4 ms
United States 32.8M 7–16 ms ≤ 3 ms

Cold nearest-neighbor touches 1–3 tree leaves regardless of corpus size — the KD tree's cost scales with query selectivity, not point count.

Sharding overhead: none

Splitting the Québec corpus into 4 geographic shards, including the corpus-wide statistics pass (how that works):

Monolithic Sharded (4)
Build (same machine, sequential) 421.5 s 423.1 s
Index size 9.54 GB 9.49 GB
Nearest + facets (cold) 4 ms / 348 KB 4.9 ms / 165 KB
Text + geo boost (cold) 389 ms / 21.5 MB 262 ms / 10.1 MB
Rankings identical (score drift 0.0)

Geo-routed lanes transfer less than the monolith because per-shard structures are smaller; text-only queries pay a fan-out that a locality routing layer will remove.

The fairest way to place rangefind is against the tools people actually reach for. This runs rangefind, Pagefind, and Orama over the same 10,000 French Wikipedia articles, each with French analysis (stemming + stopwords), and each given a competent configuration — Orama's search is title-weighted with full recall, not left on defaults. The harness is committed (bench/competitive/) so you can rerun it.

Relevance is measured with known-item queries: the query is an article's title and the correct answer is that article, so "did the engine retrieve the right page?" is analyzer-agnostic and unambiguous. Transfer is the index bytes fetched to answer a cold query — each engine's own runtime code (JS/WASM) is excluded on both sides.

Engine Model Index size recall@10 MRR Cold query transfer
rangefind static files, HTTP range 13.8 MB 1.000 0.989 90 KB (p95 174 KB)
Pagefind static files, WASM fragments 44.4 MB 1.000 0.978 225 KB (p95 875 KB)
Orama in-memory (JS) 166 MB 0.977 0.805 166 MB — the whole index

The shape of the result follows the architecture. Rangefind and Pagefind both fetch only a slice per query, so their transfer stays small; rangefind's index is ~3× smaller and its per-query transfer ~2.5× lighter here, with the top retrieval quality. Orama is fast and precise once loaded, but its in-memory model means the browser must download the entire index before the first query — 166 MB at 10k docs, and it grows linearly, which is the wall this whole project exists to avoid. The gap widens with corpus size: the million-to-billion document numbers above are territory the download-everything and index-in-browser models don't reach.

This is a deliberately narrow slice — French text retrieval on known-item queries. It says nothing about geo, vector/hybrid, or link-graph ranking, because Pagefind and Orama don't offer directly comparable lanes; both are excellent tools built for different centers of gravity (Pagefind's zero-config site DX, Orama's in-memory hybrid search). Measure your own corpus before choosing.

Quality methodology

Speed without relevance is easy. The repository carries quality harnesses that replay query sets against Lucene and Tantivy as oracles and compare ranked results, plus a search-benchmark-game harness for apples-to-apples latency. Typo correction, phrase handling, and multilingual analysis are all covered by the 220+ test suite that runs on every commit.

Reproduce it

git clone https://github.com/xjodoin/rangefind && cd rangefind && npm install
npm run bench:frwiki        # French Wikipedia end-to-end
npm run bench:osm-geo       # Luxembourg geo suite (small, fast)
npm run bench:osm-shards    # Québec sharded-vs-monolithic comparison

The head-to-head against Pagefind and Orama lives in its own workspace so its dependencies stay out of the core package:

cd bench/competitive && npm install && npx playwright install chromium
node run.mjs --docs=10000 --queries=300   # build + size + quality (rangefind, Orama, Pagefind)
node browser.mjs                          # Pagefind query + transfer in headless Chromium