benchmark comparison
altor-vec vs hnswlib-wasm
Two browser-capable HNSW options with different packaging tradeoffs.
This is one of the fairest head-to-head comparisons because both tools target approximate nearest-neighbor search in browser-friendly environments. The practical decision often comes down to packaging, ergonomics, and the exact performance profile on your corpus.
Comparison table
| Category | altor-vec | hnswlib-wasm |
|---|---|---|
| Runtime model | Browser WebAssembly HNSW tuned for a compact client-side package. | Browser-capable HNSW wrapper around hnswlib concepts. |
| Bundle size / delivery | ~54KB gzipped representative payload. | Often larger packaging footprint depending on build and wrapper details. |
| Query latency | Fast local lookup; benchmark on your corpus because HNSW tuning changes outcomes. | Also fast local lookup with performance shaped by its own index parameters and packaging. |
| Memory usage | Browser memory scales with vectors and graph parameters. | Similar browser-memory story; exact overhead depends on implementation details. |
| Features | Focused ANN API and serialization flow. | Focused ANN API with different integration ergonomics. |
| Dataset sweet spot | Frontend search experiences and shipped corpora. | Similar sweet spot: browser-friendly local ANN workloads. |
Where altor-vec wins
- Smaller delivery target is attractive when bundle budget is the primary constraint.
- Straightforward fit for apps that want a narrow API and small payload.
- Good default when product teams care most about shipping friction.
Where hnswlib-wasm wins
- Developers already invested in hnswlib-style tooling may prefer familiarity.
- May perform better on some corpora depending on tuning and implementation details.
- Different wrapper choices may fit certain build systems or environments better.
Honest decision guide
If both reach your recall target, frontend ergonomics and payload size become the real decision factors. Benchmark with your own vectors before claiming a winner.
The honest pattern across all of these benchmark pages is simple: if the search corpus should stay on the server, choose server-oriented infrastructure. If the search corpus is intentionally shipped with the product and the UX benefit of local retrieval matters more than backend scale, altor-vec is usually the more natural fit.
FAQ
Which is faster, altor-vec or hnswlib-wasm?
There is no universal answer. HNSW parameter choices, vector dimensions, and the browser runtime all affect the result.
What tends to decide this comparison in practice?
Bundle size, build tooling, and how easy it is to integrate in a browser app.
Are these better compared than server databases?
Yes. This is a more direct comparison because both live in the local ANN category.
Get started: npm install altor-vec · GitHub
Benchmark methodology
These measurements reflect altor-vec running in a controlled browser environment. All queries execute against a pre-built HNSW index loaded from a JSON file — no embedding generation time is included. Embeddings are generated once at build time.
| Parameter | Value |
|---|---|
| Index size | 10,000 vectors |
| Dimensions | 384 (all-MiniLM-L6-v2) |
| HNSW M | 16 |
| ef_construction / ef_search | 200 / 50 |
| k | 5 |
| Browser | Chrome 124, M2 MacBook Pro |
| Measurement | p50/p95 of 1,000 consecutive queries |
altor-vec latency (10K × 384d)
| Metric | Result |
|---|---|
| p50 query latency | 0.4ms |
| p95 query latency | 0.8ms |
| Index load time | ~35ms |
| Memory footprint | ~17MB |
| WASM bundle size | 54KB gzipped |
What these numbers mean
Sub-millisecond latency means search is effectively instant from the user's perspective. Human perception of "instantaneous" begins around 100ms — altor-vec at p95 (0.8ms) is 125× faster than a cloud search call at 100ms total round-trip.
The 17MB footprint for 10K vectors fits easily in modern browser memory. For 100K vectors at 384 dimensions, expect ~170MB — viable on desktop, worth testing on mobile.
Run your own benchmark
import init, { WasmSearchEngine } from 'altor-vec';
await init();
const engine = WasmSearchEngine.from_vectors(vectors, DIM, 16, 200, 50);
const query = new Float32Array(DIM);
const times = [];
for (let i = 0; i < 1000; i++) {
const t = performance.now();
engine.search(query, 5);
times.push(performance.now() - t);
}
times.sort((a, b) => a - b);
console.log('p50:', times[500].toFixed(2) + 'ms');
console.log('p95:', times[950].toFixed(2) + 'ms');