vector-db
Vector Database Engine
A search engine that finds things by meaning rather than exact words, the way a librarian can hand you the right book from a vague description. It was built from the original research paper rather than a ready-made library, then tested on 17,000 pieces of text: its matches were at least as accurate as FAISS, the library professionals use, though FAISS answers each search 10 to 13 times faster.
Overview
A vector database engine written from scratch in Python, built around an HNSW index implemented directly from the paper rather than wrapping a library. Approximate nearest-neighbor search with configurable recall, exact brute-force ground truth, metadata-filtered kNN, crash-safe WAL persistence, and a small HTTP server.
Key features
- An HNSW index from scratch: a multi-layer graph, probabilistic level assignment, greedy per-layer search, the Algorithm-4 neighbor-selection heuristic with keep_pruned_connections, and configurable M, efConstruction, and efSearch across L2, cosine, and inner-product metrics.
- A flat brute-force index for exact recall ground truth.
- Soft delete with tombstones and a compact() rebuild.
- Crash-safe persistence: a binary snapshot plus an fsync'd write-ahead log, verified by a test that kills a real subprocess mid-batch.
- Metadata and filtered kNN with both pre-filter (exact) and post-filter (approximate) strategies, both tested.
- A FastAPI server with a Python client.
Benchmark
18,000 real 20-Newsgroups embeddings (text-embedding-005, 768-dim), 17,000 indexed and 1,000 held out. M = 16, efConstruction = 200, k = 10, efSearch swept.
Recall vs FAISS
| efSearch | ours recall@10 | ours p50 ms | FAISS recall@10 |
|---|---|---|---|
| 10 | 0.9473 | 1.67 | 0.9038 |
| 40 | 0.9938 | 3.73 | 0.9886 |
| 80 | 0.9980 | 5.38 | 0.9970 |
| 160 | 0.9994 | 10.73 | 0.9987 |
| 320 | 0.9997 | 17.97 | 0.9991 |
What the numbers say
At every matched efSearch our recall is at least as high as FAISS, which confirms the graph and search are implemented correctly. FAISS is roughly 10 to 13x faster per query and builds the index in seconds rather than about 20 minutes, because it is optimized C with SIMD and this is CPython with per-node numpy calls. That gap is expected and is the whole reason libraries like FAISS exist.