benchmark comparison
altor-vec vs Server-Side Vector Search
When local browser retrieval wins and when server-side retrieval clearly wins.
This is the umbrella tradeoff behind every individual comparison page. Browser vector search and server vector search are both useful, but they optimize different things: one optimizes delivery and local UX, the other optimizes centralized control and scale.
Comparison table
| Category | altor-vec | Server-Side Vector Search |
|---|---|---|
| Runtime model | Index runs in the browser session next to the UI. | Index runs on a server, managed service, or database cluster. |
| Bundle size / delivery | You ship the library and corpus to the client. | You ship little or nothing to the client, but every query traverses the network. |
| Query latency | Best-case interactive latency because the search is local. | Higher floor because network is part of every query, but better for central shared corpora. |
| Memory usage | Client pays the memory cost. | Server pays the memory and storage cost. |
| Features | Great for offline, privacy, and embedded UX; weak for centralized operations. | Great for writes, ACLs, filtering, observability, and shared large datasets. |
| Dataset sweet spot | Safe-to-ship, moderate-size, mostly static corpora. | Private, massive, multi-user, or fast-changing corpora. |
Where altor-vec wins
- Offline and low-latency UX.
- Zero per-query API dependency.
- Simple architecture for frontend-owned search experiences.
Where Server-Side Vector Search wins
- Large mutable datasets.
- Access control and backend integration.
- Centralized logging, scaling, and team operations.
Honest decision guide
Browser search wins when retrieval is part of the interface itself. Server search wins when retrieval is part of the infrastructure. Most teams should choose based on that boundary first, not on raw ANN marketing claims.
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
Can browser search replace server search completely?
Only for the subset of use cases where the corpus is safe to ship and moderate in size.
What is the biggest advantage of server-side search?
Control: private data, writes, filtering, observability, and shared infrastructure.
What is the biggest advantage of browser-side search?
Local latency and product simplicity. The UI can search instantly without asking another service for every interaction.
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');