backend-selection.md

reference

← Back to skill

Content hash: 70a9c7ba7d37a2d84009f12d98fda40d17a055a34fc8a030d87e7a04e523a4a6
## Vector Database Selection Guide

### Decision matrix
| Requirement | Choose |
|-------------|--------|
| Already running Postgres | pgvector |
| Single-node, zero-ops | sqlite-vec |
| High QPS, distributed | Qdrant / Milvus |
| Managed, no infra | Pinecone |
| Filtering-heavy | Qdrant / Weaviate |
| Multi-tenancy at scale | Milvus / Qdrant |

### Index parameters (recall dials)
| Parameter | Engine | Higher = |
|-----------|--------|---------|
| `M` (HNSW) | pgvector, Milvus, Qdrant | Better recall, more memory |
| `ef_search` | pgvector, Milvus | Better recall, slower query |
| `lists`/`nlist` (IVF) | pgvector, Faiss | More cells, faster build |
| `probes`/`nprobe` | pgvector, Faiss | Better recall, slower query |

### Distance metrics
| Metric | When | Notes |
|--------|------|-------|
| Cosine | Text/semantic | Normalize vectors first |
| L2 (Euclidean) | General | Sensitive to magnitude |
| Inner product | Normalized | Equals cosine when normalized |

### sqlite-vec setup
```sql
.load ./vec0
CREATE VIRTUAL TABLE items USING vec0(embedding float[384]);
INSERT INTO items (rowid, embedding) VALUES (1, ?);
SELECT rowid, distance FROM items
WHERE embedding MATCH ? ORDER BY distance LIMIT 10;
```

### pgvector setup
```sql
CREATE EXTENSION vector;
CREATE TABLE items (id bigserial, embedding vector(1536));
CREATE INDEX ON items USING hnsw (embedding vector_cosine_ops);
SELECT id, 1 - (embedding <=> :query) AS similarity
FROM items ORDER BY embedding <=> :query LIMIT 10;
```

### Recall maintenance
- [ ] Return scores with every query (enable thresholding)
- [ ] Reindex on any embedding model change
- [ ] VACUUM/ANALYZE after bulk loads
- [ ] Warm up cold indexes with real queries
- [ ] Measure recall@k on a labeled eval set, not vibes