
Fast, lightweight, in-process vector database with HNSW indexing, SIMD-accelerated
distance calculations, metadata filtering, E8 lattice quantization, and optional
persistence via Sled or RocksDB.
§Why embedvec?
- Pure Rust — No C++ dependencies (unless using RocksDB), safe and portable
- Blazing Fast — AVX2/FMA SIMD acceleration, optimized HNSW with O(1) lookups
- Memory Efficient — E8 quantization provides 4-6× compression with <5% recall loss
- Flexible Persistence — Choose between Sled (pure Rust) or RocksDB (high performance)
- Production Ready — Async API, metadata filtering, batch operations
§Benchmarks (768-dim vectors, 10k dataset)
| Operation | Time | Throughput |
| Search (ef=32) | 3.0 ms | 3,300 queries/sec |
| Search (ef=64) | 4.9 ms | 2,000 queries/sec |
| Search (ef=128) | 16.1 ms | 620 queries/sec |
| Insert (768-dim) | 25.5 ms/100 | 3,900 vectors/sec |
| Distance (cosine) | 122 ns/pair | 8.2M ops/sec |
| Distance (dot) | 91 ns/pair | 11M ops/sec |
Benchmarks on AMD Ryzen 9 / Intel i9, AVX2 enabled. Run cargo bench to reproduce.
§Features
| Feature | Description |
| HNSW Indexing | Hierarchical Navigable Small World graph for O(log n) ANN search |
| SIMD Distance | AVX2/FMA accelerated cosine, euclidean, dot product |
| E8 Quantization | Lattice-based compression (4-6× memory reduction) |
| Metadata Filtering | Composable filters: eq, gt, lt, contains, AND/OR/NOT |
| Dual Persistence | Sled (pure Rust) or RocksDB (high performance) |
| Async API | Tokio-compatible async operations |
| Python Bindings | PyO3-based interop (feature-gated) |
§Quick Start
use embedvec::{Distance, EmbedVec, FilterExpr};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut db = EmbedVec::new(768, Distance::Cosine, 32, 200).await?;
db.add(&vec![0.1; 768], serde_json::json!({"doc_id": "123", "category": "tech"})).await?;
let filter = FilterExpr::eq("category", "tech");
let results = db.search(&vec![0.15; 768], 10, 100, Some(filter)).await?;
for hit in results {
println!("id: {}, score: {:.4}", hit.id, hit.score);
}
Ok(())
}
§With Persistence
use embedvec::{Distance, EmbedVec, BackendConfig, BackendType};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = EmbedVec::with_persistence("/tmp/vectors.db", 768, Distance::Cosine, 32, 200).await?;
Ok(())
}
§E8 Quantization (4-6× Memory Savings)
use embedvec::{EmbedVec, Distance, Quantization};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = EmbedVec::builder()
.dimension(768)
.metric(Distance::Cosine)
.quantization(Quantization::e8_default()) .build()
.await?;
Ok(())
}
§Feature Flags
| Flag | Description | Default |
persistence-sled | Sled persistence backend | ✓ |
persistence-rocksdb | RocksDB persistence backend | ✗ |
async | Tokio async API | ✓ |
python | PyO3 Python bindings | ✗ |
simd | Explicit SIMD (auto-detected) | ✗ |
§Memory Usage (768-dim vectors)
| Mode | Bits/Dim | Memory/Vector | 1M Vectors |
| Raw (f32) | 32 | 3.1 KB | ~3.1 GB |
| E8 10-bit | ~1.25 | ~220 B | ~220 MB |
§License
MIT OR Apache-2.0