A high-performance, in-memory vector database written in C++20, with SIMD-accelerated distance computation, three search backends, write-ahead-log persistence, and a REST API.
- Three search backends, selectable per database:
- Exact (KD-tree) — exact nearest-neighbor search
- LSH — locality-sensitive hashing for fast approximate search
- HNSW — hierarchical navigable small-world graphs (hnswlib-style) for high-recall approximate search
- SIMD distance kernels — AVX2/FMA on x86-64, NEON on ARM (Apple Silicon), with scalar fallbacks; toggleable at runtime
- Durability — write-ahead log with automatic checkpointing, atomic file writes, and a recovery state machine that replays the log on startup
- Deletes and updates on approximate indexes — LSH/HNSW graphs cannot delete in place, so the database tracks stale index entries, over-fetches and re-ranks search candidates against the live vector set, and rebuilds indexes once stale entries outnumber live ones
- LRU query cache keyed on (query, k), invalidated on every mutation
- Atomic batch operations — insert / update / delete many vectors per call
- REST API server (cpp-httplib) exposing the full CRUD + search + admin surface
- Thread-safe — a concurrency test hammers parallel inserts and searches
src/core/ Vector type, KD-tree, VectorDatabase orchestration
src/algorithms/ HNSW and LSH approximate indexes
src/optimizations/ SIMD kernels (AVX2 / NEON), parallel processing helpers
src/features/ WAL persistence, atomic batch insert, query cache, recovery
src/api/ REST server (vector_db_server)
src/utils/ Distance metrics (Euclidean, cosine), RNG
tests/ GoogleTest suite (17 tests)
bench/ Reproducible benchmark harness with JSON output
Requires CMake ≥ 3.20 and a C++20 compiler. Dependencies (nlohmann/json, cpp-httplib, GoogleTest) are fetched automatically.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -jctest --test-dir build --output-on-failureThe suite covers hand-computed distance values, SIMD-vs-scalar agreement, KD-tree correctness against brute force, HNSW/LSH recall floors, CRUD round-trips, delete/update visibility in search, cache behavior, batch atomicity, checkpoint/recovery, and concurrent access.
There is also a standalone smoke test that runs all three backends end to end:
./build/basic_usage./build/vector_db_server --dims 128 --port 8080# Insert
curl -X POST localhost:8080/vectors \
-d '{"key": "doc1", "vector": [0.1, 0.2, ...], "metadata": "optional"}'
# Search
curl -X POST localhost:8080/search -d '{"query": [0.1, 0.2, ...], "k": 10}'
# CRUD
curl localhost:8080/vectors/doc1
curl -X DELETE localhost:8080/vectors/doc1
# Health / stats
curl localhost:8080/health
curl localhost:8080/statsBatch endpoints (/vectors/batch/*), recovery controls (/recovery/*), and
runtime configuration (algorithm, distance metric, SIMD toggle) are also exposed.
A reproducible harness measures insert throughput, query latency
(p50/p95/p99), recall-vs-latency Pareto curves for HNSW (ef_search sweep) and
LSH (table/hash sweep), and SIMD-vs-scalar speedup:
./build/bench/vdb_bench # full run, writes bench/results/results.json
./build/bench/vdb_bench --quick # smaller sizes for CIResults include machine/compiler metadata and a fixed RNG seed so runs are
comparable. See bench/results/results.json for
the latest numbers from an Apple M-series machine.
vector-db can be consumed from another CMake project via add_subdirectory,
which exposes the vector_db::vdb_core target and the single public header
<vdb/vector_index.hpp>:
add_subdirectory(path/to/vector-db)
target_link_libraries(app PRIVATE vector_db::vdb_core)#include <vdb/vector_index.hpp>
int main() {
vdb::IndexOptions options;
options.backend = vdb::IndexOptions::Backend::HNSW;
options.metric = vdb::IndexOptions::Metric::Cosine;
vdb::VectorIndex index(4, options);
index.insert("a", {1.0f, 0.0f, 0.0f, 0.0f});
index.insert("b", {0.0f, 1.0f, 0.0f, 0.0f});
auto results = index.search({1.0f, 0.0f, 0.0f, 0.0f}, /*k=*/1);
return results.empty() ? 1 : 0;
}nlohmann_json is fetched automatically as a dependency of the core
persistence layer. googletest and httplib are fetched only when
VDB_BUILD_TESTS / VDB_BUILD_SERVER are enabled, which is the default for
top-level builds but not when the project is pulled in via add_subdirectory.
See examples/consumer for a minimal end-to-end
consumer project exercised by CI.
- Source of truth is an in-memory hash map of key → vector. Indexes are acceleration structures; search results are always validated against the map, which is what makes deletes/updates correct on top of append-only ANN indexes.
- Persistence follows a WAL + checkpoint model: every mutation is logged before acknowledgment, checkpoints snapshot the full map atomically (write-temp-then-rename), and recovery replays the log over the last checkpoint.
- Locking is a single database-level mutex; the KD-tree uses tombstones for O(1) logical deletion.