migration guide
Migrate from Pinecone to altor-vec
Replace Pinecone's $0.096/1M-read cloud vector database with free browser-native HNSW search using altor-vec. Export your vectors, convert to Float32Array, ship as a static index — zero per-query billing forever.
When migration makes sense
- You are paying for Pinecone reads on a public-facing search surface that could run client-side
- Your dataset is under ~100K vectors and doesn't need Pinecone's billion-scale infrastructure
- Privacy: query text should not leave the user's device or hit your API
What you give up
Migration is not always the right call. altor-vec cannot replace Pinecone for:
- Real-time upserts: altor-vec indexes rebuild on deploy, not on every write
- Metadata filtering: Pinecone's filter-by-metadata queries require post-retrieval filtering with altor-vec
- Multi-namespace support and production-scale observability
Step-by-step migration
npm install altor-vec @xenova/transformers// 1. Export vectors from Pinecone (Node.js script)
import { Pinecone } from '@pinecone-database/pinecone';
import { writeFileSync } from 'fs';
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY });
const index = pc.index('your-index-name');
// List and fetch all vectors
const listResult = await index.listPaginated({ prefix: '' });
const ids = listResult.vectors.map(v => v.id);
const fetchResult = await index.fetch(ids);
const vectors = Object.values(fetchResult.records);
writeFileSync('vectors-export.json', JSON.stringify(vectors));
console.log(`Exported ${vectors.length} vectors`);
// 2. Build altor-vec index (same script or separate build step)
import init, { WasmSearchEngine } from 'altor-vec';
await init();
const DIM = 1536; // or 384, match your Pinecone namespace dimension
const vecs = new Float32Array(vectors.length * DIM);
for (const [i, v] of vectors.entries()) {
vecs.set(v.values, i * DIM);
}
const engine = WasmSearchEngine.from_vectors(vecs, DIM, 16, 200, 50);
writeFileSync('public/search-index.json', engine.to_json());
console.log('Browser-ready index written to public/search-index.json');
After migration
Once your index is built and deployed to public/search-index.json, load it in the browser:
import init, { WasmSearchEngine } from 'altor-vec';
import { pipeline } from '@xenova/transformers';
await init();
const embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
const resp = await fetch('/search-index.json');
const engine = WasmSearchEngine.from_json(await resp.text());
async function search(query, k = 5) {
const out = await embedder(query, { pooling: 'mean', normalize: true });
const hits = JSON.parse(engine.search(new Float32Array(out.data), k));
return hits; // [{id, score}] - map id back to your metadata
}
Frequently asked questions
How much does Pinecone cost vs altor-vec?
Pinecone's serverless tier costs $0.096 per million vector reads. For a site with 10,000 daily searches, that is ~$35/month. altor-vec costs $0 — search runs in the browser with no API call.
Can altor-vec handle the same use cases as Pinecone?
altor-vec handles browser-scale use cases well: documentation search, product search, RAG retrieval, autocomplete — all up to ~100K vectors. Pinecone handles billion-scale, multi-tenant, server-side workloads that altor-vec is not designed for.
How do I export vectors from Pinecone?
Use the Pinecone JS client: index.listPaginated() to get IDs, then index.fetch(ids) to retrieve vector values. Convert the values arrays to a Float32Array and pass to WasmSearchEngine.from_vectors(). See the code example above.
Is altor-vec as fast as Pinecone for similarity search?
For small indexes, altor-vec is faster end-to-end because it eliminates network latency. A 0.4ms local WASM search beats a 0.1ms Pinecone query + 30ms network round-trip. For billion-scale workloads, Pinecone wins in throughput.