Skip to main content

In-memory vector database with HNSW, BM25, and hybrid search

Project description

vectors.db icon

vectors.db

A lightweight, in-memory vector database with HNSW indexing, BM25 full-text search, and hybrid retrieval.

CI

Features

  • HNSW vector search with configurable M, ef_construction, ef_search
  • BM25 keyword search with Okapi BM25 scoring
  • Hybrid search combining vector + keyword via RRF or linear fusion
  • Scalar quantization (f32 -> u8) for memory-efficient SIMD-friendly storage, with optional raw f32 vectors for maximum recall
  • Write-Ahead Log (WAL) with CRC32 checksums and fsync for crash recovery
  • Encryption at rest — AES-256-GCM for snapshots and WAL, with key file or env var
  • Auto-compaction — automatic index rebuild when deleted nodes exceed a configurable threshold (default 20%)
  • WAL streaming replication — active-passive HA with automatic snapshot sync and real-time WAL streaming
  • Structured audit logging — WHO/WHAT/WHEN for all mutations, filterable via RUST_LOG=audit=info
  • RBAC with collection-scoped multi-tenancy — Read/Write/Admin roles with optional per-key collection restrictions
  • Prometheus metrics at /metrics with prebuilt Grafana dashboard
  • Request timeout (30s) and rate limiting (100 req/s)
  • Batch insert up to 1000 documents per request
  • Multiple distance metrics: Cosine, Euclidean, Dot Product

Quick Start

Python library

pip install maturin
cd crates/python && maturin develop --release
import vectorsdb

# Persistent database with WAL crash recovery
db = vectorsdb.VectorDB(data_dir="./data")
# or: db = vectorsdb.VectorDB()  # ephemeral (in-memory only)

db.create_collection("docs", dimension=3)

db.insert("docs", "hello world", [1.0, 0.0, 0.0], metadata={"tag": "greeting"})
db.insert("docs", "goodbye moon", [0.0, 1.0, 0.0])

# Vector search
results = db.search("docs", query_embedding=[1.0, 0.0, 0.0], k=5)
print(results[0].text)      # "hello world"
print(results[0].score)     # 1.0
print(results[0].metadata)  # {"tag": "greeting"}

# Keyword search
results = db.search("docs", query_text="moon", k=5)

# Hybrid search (vector + keyword)
results = db.search("docs", query_embedding=[1.0, 0.0, 0.0], query_text="hello", k=5)

# Filtered search
results = db.search("docs", query_embedding=[1.0, 0.0, 0.0], k=5, filter={
    "must": [{"field": "tag", "op": "eq", "value": "greeting"}]
})

# Snapshot + WAL truncation
db.save("docs")       # saves to ./data/docs.vdb, truncates WAL
db.compact()          # saves ALL collections + truncates WAL

Full IDE autocomplete and type hints are included via PEP 561 stubs. See examples/ for more usage patterns.

REST server

From source

cargo run --release -- --port 3030 --data-dir ./data

Docker

docker build -t vectors-db .
docker run -p 3030:3030 -v vectors-data:/data vectors-db

Docker Compose (primary + standby)

docker compose up -d                           # primary + standby
docker compose --profile monitoring up -d      # + Prometheus + Grafana

Grafana dashboard at http://localhost:3000, Prometheus at http://localhost:9090.

First steps

# Create a collection
curl -X POST http://localhost:3030/collections \
  -H "Content-Type: application/json" \
  -d '{"name": "my_collection", "dimension": 3}'

# Insert a document
curl -X POST http://localhost:3030/collections/my_collection/documents \
  -H "Content-Type: application/json" \
  -d '{"text": "hello world", "embedding": [0.1, 0.2, 0.3]}'

# Search
curl -X POST http://localhost:3030/collections/my_collection/search \
  -H "Content-Type: application/json" \
  -d '{"query_embedding": [0.1, 0.2, 0.3], "k": 5}'

API Reference

Method Path Description
GET /health Health check (no auth required)
GET /metrics Prometheus metrics (no auth required)
POST /collections Create a collection
GET /collections List all collections
DELETE /collections/:name Delete a collection
POST /collections/:name/documents Insert a document
POST /collections/:name/documents/batch Batch insert (max 1000)
GET /collections/:name/documents/:id Get document by ID
DELETE /collections/:name/documents/:id Delete document
POST /collections/:name/search Vector, keyword, or hybrid search
POST /collections/:name/save Save collection snapshot to disk
POST /collections/:name/load Load collection snapshot from disk
POST /admin/compact Save all collections and truncate WAL
POST /admin/promote Promote standby to primary (standby only)

Create Collection

POST /collections
{
  "name": "my_collection",
  "dimension": 768,
  "m": 16,
  "ef_construction": 200,
  "ef_search": 50,
  "distance_metric": "cosine",
  "store_raw_vectors": false
}

store_raw_vectors (default false): when true, stores raw f32 vectors alongside quantized u8 for exact distance reranking (+0.75% recall, 5x RAM). See Benchmarks for detailed comparison.

Insert Document

POST /collections/:name/documents
{
  "text": "document content",
  "embedding": [0.1, 0.2, ...],
  "metadata": {"key": "value"}
}

Search

POST /collections/:name/search
{
  "query_text": "search query",
  "query_embedding": [0.1, 0.2, ...],
  "k": 10,
  "min_similarity": 0.5,
  "alpha": 0.7,
  "fusion_method": "rrf"
}

Configuration

Environment Variables

Variable Description
VECTORS_DB_API_KEY Single bearer token for API authentication. If unset, auth is disabled.
VECTORS_DB_API_KEYS JSON array for RBAC with optional collection scoping. See below.
VECTORS_DB_ENCRYPTION_KEY 64-character hex string (32 bytes) for AES-256-GCM encryption at rest.
RUST_LOG Log level filter (e.g., vectorsdb_server=info, audit=info for audit events)

Multi-Tenant RBAC

Use VECTORS_DB_API_KEYS to assign roles and restrict keys to specific collections:

VECTORS_DB_API_KEYS='[
  {"key": "admin-key", "role": "admin"},
  {"key": "tenant-a", "role": "write", "collections": ["tenantA_*"]},
  {"key": "reader", "role": "read", "collections": ["public", "shared_*"]}
]'
  • Roles: read < write < admin (each inherits lower permissions)
  • collections (optional): restricts the key to collections matching the listed patterns. Supports exact names ("public") and prefix globs ("tenantA_*"). Omit for unrestricted access.
  • Admin bypass: Admin keys always have full access regardless of collections.
  • GET /collections is filtered to only show accessible collections for scoped keys.

CLI Arguments

Argument Default Description
--port, -p 3030 Port to listen on
--data-dir, -d ./data Directory for WAL and snapshots
--snapshot-interval 300 Auto-snapshot interval in seconds (0 = disabled)
--auto-compact-ratio 0.2 Rebuild indices when >N% of nodes are deleted (0.0 = disabled)
--encryption-key-file Path to encryption key file (32 raw bytes or 64-char hex). Overrides env var.
--wal-strict false Fail startup if WAL replay encounters errors
--replication-port 0 (disabled) TCP port for replication listener (primary mode)
--standby-of host:port of primary to replicate from (standby mode)
--replication-buffer 1024 Broadcast channel capacity for WAL streaming

Architecture

                        ┌─────────────────────────────────┐
                        │          HTTP API (Axum)         │
                        │  auth · metrics · rate-limit     │
                        └──────────────┬──────────────────┘
                                       │
                        ┌──────────────▼──────────────────┐
                        │           Database               │
                        │   HashMap<String, Collection>    │
                        └──────────────┬──────────────────┘
                                       │
              ┌────────────────────────┼────────────────────────┐
              │                        │                        │
   ┌──────────▼─────────┐  ┌──────────▼─────────┐  ┌──────────▼─────────┐
   │    HNSW Index       │  │   BM25 Index       │  │   Hybrid Search    │
   │  scalar quantized   │  │  inverted index    │  │   RRF / linear     │
   └──────────┬──────────┘  └────────────────────┘  └────────────────────┘
              │
   ┌──────────▼──────────┐
   │    Distance Metrics  │
   │  cos · l2 · dot     │
   └─────────────────────┘

   Persistence:  WAL (append + CRC32 + fsync) → Snapshot (.vdb bincode)
   Replication:  WAL streaming (TCP) → Primary → Standby

Benchmarks

Results on Apple Silicon (M-series), single-threaded, SIFT-128 (1M vectors, 128d, Euclidean):

Compact mode (store_raw_vectors=false, default)

ef_search Recall@10 QPS Memory
10 0.7695 22,566 122 MB
40 0.9450 9,152
120 0.9853 3,661
200 0.9898 2,325
400 0.9916 1,275

Build: 1,852 inserts/s

Exact mode (store_raw_vectors=true)

ef_search Recall@10 QPS Memory
10 0.7716 22,940 610 MB
40 0.9494 8,759
120 0.9924 3,674
200 0.9972 2,370
400 0.9990 1,277

Build: 1,912 inserts/s

Compact mode uses 5x less memory with only ~0.7% recall loss. Exact mode matches hnsw(nmslib) at 0.9990 recall.

High-dimensional (768d, 1536d)

Synthetic data at LLM embedding dimensions. Compact vs exact at ef_search=400:

Dimension Compact Recall Exact Recall Compact QPS Exact QPS
768d (100K) 0.9860 0.9993 1,209 1,311
1536d (25K) 0.9880 1.0000 1,757 1,341

At high dimensions, exact mode is recommended for maximum recall (+1.3% at 768d). Build speed is comparable between modes thanks to cached dequantization during construction.

Filtered search & concurrency

Benchmark Result
Filtered 50% selectivity 0.9913 recall, 1,282 QPS
Filtered 1% selectivity 0.9953 recall, 46 QPS
8-thread concurrent 10,878 QPS (5.0x scaling)

Run benchmarks:

cargo bench

License

AGPL-3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vectors_db-0.1.0.tar.gz (103.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

vectors_db-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (503.4 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

vectors_db-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (490.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

vectors_db-0.1.0-cp312-cp312-win_amd64.whl (393.9 kB view details)

Uploaded CPython 3.12Windows x86-64

vectors_db-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (503.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

vectors_db-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (490.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

vectors_db-0.1.0-cp312-cp312-macosx_11_0_arm64.whl (442.2 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

vectors_db-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl (479.9 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

vectors_db-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (504.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

vectors_db-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (492.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

vectors_db-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (504.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

vectors_db-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (492.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

vectors_db-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (505.6 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

vectors_db-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (493.0 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64

File details

Details for the file vectors_db-0.1.0.tar.gz.

File metadata

  • Download URL: vectors_db-0.1.0.tar.gz
  • Upload date:
  • Size: 103.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.12.2

File hashes

Hashes for vectors_db-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2bfd9cbb9b646e57d4ceb56f13db1cbe88695d6df64acdecd13cee1e6e0a06a5
MD5 7bff2f429d98e86595b6efe64052cd4a
BLAKE2b-256 59ec12d34f5a181070e3f18b07e34561092180a58d3ae1ff7ee938f56fef3612

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fbb81fcf5819890ade52aa9f96f8c8f7243ccf62f4ec733e6d7fd73576408231
MD5 98535afb84e19a12ef8af8a6beba9861
BLAKE2b-256 88707d17d293901eb7161ba4ff5bc5df159e9b52c58c7d43da871d2304ec2681

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7746b39fce166a4a82e15fb5ccf871c97800f4caa0aa65f557646b9d56e48297
MD5 158af2cd422f2f208fa35c8321bef02c
BLAKE2b-256 1973cd74c7f7fad8add18b0b1434286c9bf116003a8aa94a26eca12a111c82f0

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 974f78125acee3103d39049dd4e8de6f22037fde9de3854cdd79724eb047e7f0
MD5 28a913900a427a4e6dede955bd2e6720
BLAKE2b-256 e99f8bfb80d699f1c7068be88c6ecd01414c9892df8902a46077df46bfa0b325

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d68a7726c61f7aae4c48f798ddb6cb6cb9b64cf75b76e02dd1649a2602b2e7e1
MD5 c9d287233f1e5e4a2442a1c260b4e91b
BLAKE2b-256 2dacc43d8f652a762dbc3e0dddd402909c5555adb3893a79cdec7a5a653989a1

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5faff3df760a2492e1661a0232cbd3ad824623748b2ea4ea86be9895f2f0596e
MD5 6d0be2d77e6911409db21d1ce9c436de
BLAKE2b-256 b6cfb2a7bbfccdb2a422961883a2df45ef6188314c1e4f73ad2624504b1b09bc

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 80b6bbb19673be6a120f83c09c15299baa3b2a4fc3f14d2d1a12984d87aa2e20
MD5 f75ec4e39038c3209b8e1c970fbb1140
BLAKE2b-256 e8dfeaadae6a6b6c18982cea4c47fa23ea7ddc7da72db171ee4a2f2b7b9d1b8a

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 66fbf67bb59f5519d61b3cc1d6ae027d97071ba8810ca622b6be5e872c442eda
MD5 f139c640dd5645dfbdfcfd6fbea49550
BLAKE2b-256 e1707348d4740e0182dfb02ae17e1219178a96cd60f230a8658b8566cb8312fe

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ceba279695c2e33fc8a96d0cad6af462d7844e52f5cf62ee4dab2edf28548ca8
MD5 3e7df22695733de3ac8a76382399c80c
BLAKE2b-256 bce755d9b1ecf508e8115ac227956d1d7ef9f9bd4050b1710599aade507d466a

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5c80429845b9d64c2df5c0654cc98d77f27ed2b1ff671b8f0fe9a84f1f964308
MD5 d7f31a5153d08607a88914a776c63c9f
BLAKE2b-256 3ff674e14a519b81da0432d7c01adab35c30f8e816e708fcc48d99f4b5a35eb4

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 89d9b6fb7cc3a6f7e87975c9631809f8701524cd46493be659bf7ef7a795b252
MD5 e8f96bdb7080c21ec09ae6cb3d93603d
BLAKE2b-256 8b2cb83110625599c65895c564507f479603d12964087e955343769e0dc45afe

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7b76f776e44a2f447d9f6057aff821e1fbff33a9877b15accf1c6dfaa22ae79f
MD5 0f3cb67d13fec3efe6b5516543f20fe4
BLAKE2b-256 fa6941fd523b5d01a0d918938a88a01ec333a72e2613acdc6b0f5a4ccc84e219

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8c0062133f66ddc1c539b33515171fd959c7fe32167e9d9481bea30b8eec5443
MD5 f26eef592483088ffde197e54c81dfb9
BLAKE2b-256 4655ece64cbd9630a9d7a15603e8cc8556ff1b4efdeb02a16ff37ee50cad5c3e

See more details on using hashes here.

File details

Details for the file vectors_db-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for vectors_db-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 45797a83175685c06b646aab70d8436062350ded2bee090f6518f75c305db1b3
MD5 6d9fb64c51ed60f109b95d0dfee53c38
BLAKE2b-256 310b3950f7d44f72bf8b3b3f46ccbba816d218c0775d14e5dcab2e1848ecfb9e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page