vecdb
High-performance mutable persistent vectors built on rawdb.
Features
- Vec-like API:
push,update,truncate, delete by index with sparse holes - Multiple storage formats:
- Raw:
BytesVec,ZeroCopyVec(uncompressed) - Compressed:
PcoVec,LZ4Vec,ZstdVec
- Raw:
- Computed vectors:
EagerVec(stored computations),LazyVecFrom1/2/3(on-the-fly computation) - Rollback support: Time-travel via stamped change deltas without full snapshots
- Sparse deletions: Delete elements leaving holes, no reindexing required
- Thread-safe: Concurrent reads with exclusive writes
- Blazing fast: See benchmarks
- Lazy persistence: Changes buffered in memory, persisted only on explicit
flush()
Not Suited For
- Key-value storage - Use
fjallorredb - Variable-sized types - Types like
String,Vec<T>, or dynamic structures - ACID transactions - No transactional guarantees (use explicit rollback instead)
Install
Quick Start
use ;
use Path;
Type Constraints
vecdb works with fixed-size types:
- Numeric primitives:
u8,i32,f64, etc. - Fixed arrays:
[T; N] - Structs with
#[repr(C)] - Types implementing
zerocopy::FromBytes + zerocopy::AsBytes(forZeroCopyVec) - Types implementing
Bytestrait (forBytesVec,LZ4Vec,ZstdVec) - Numeric types implementing
Pcotrait (forPcoVec)
Use #[derive(Bytes)] or #[derive(Pco)] from vecdb_derive to enable custom wrapper types.
Vector Variants
Raw (Uncompressed)
BytesVec<I, T> - Custom serialization via Bytes trait
use ;
;
let mut vec: =
import?;
ZeroCopyVec<I, T> - Zero-copy mmap access (fastest random reads)
use ZeroCopyVec;
let mut vec: =
import?;
Compressed
PcoVec<I, T> - Pcodec compression (best for numeric data, excellent compression ratios)
use PcoVec;
let mut vec: =
import?;
LZ4Vec<I, T> - LZ4 compression (fast, general-purpose)
use LZ4Vec;
let mut vec: =
import?;
ZstdVec<I, T> - Zstd compression (high compression ratio, general-purpose)
use ZstdVec;
let mut vec: =
import?;
Computed Vectors
EagerVec<V> - Wraps any stored vector to enable eager computation methods
Stores computed results on disk, incrementally updating when source data changes. Use for derived metrics, aggregations, transformations, moving averages, etc.
use EagerVec;
let mut derived: =
import?;
// Compute methods store results on disk
// derived.compute_add(&source1, &source2)?;
// derived.compute_sma(&source, 20)?;
LazyVecFrom1/2/3<...> - Lazily computed vectors from 1-3 source vectors
Values computed on-the-fly during iteration, nothing stored on disk. Use for temporary views or simple transformations.
use LazyVecFrom1;
let lazy = init;
// Computed during iteration, not stored
for value in lazy.iter
Core Operations
Write and Persistence
// Push values (buffered in memory)
vec.push;
vec.push;
// write() moves pushed values to storage (visible for reads)
vec.write?;
// flush() calls write() + region().flush() for durability
vec.flush?;
db.flush?; // Also flush database metadata
Updates and Deletions
// Update element at index (works on stored data)
vec.update?;
// Delete element (creates a hole at that index)
let reader = vec.create_reader;
vec.take?;
drop;
// Holes are tracked and can be checked
if vec.holes.contains
// Reading a hole returns None
let reader = vec.create_reader;
assert_eq!;
Rollback with Stamps
Rollback uses stamped change deltas - lightweight compared to full snapshots.
use Stamp;
// Create initial state
vec.push;
vec.push;
vec.stamped_flush_with_changes?;
// Make more changes
vec.push;
vec.update?;
vec.stamped_flush_with_changes?;
// Rollback to previous stamp (undoes changes from stamp 2)
vec.rollback?;
assert_eq!;
// Rollback before a stamp (undoes everything including stamp 1)
vec.rollback_before?;
assert_eq!;
Configure number of stamps to keep:
let options =
.into
.with_saved_stamped_changes; // Keep last 10 stamps
let vec = import_with?;
When To Use
Perfect for:
- Storing large
Vecs persistently on disk - Append-only or append-mostly workloads
- High-speed sequential reads
- High-speed random reads (improved with
ZeroCopyVec) - Space-efficient storage for numeric time series (improved with
PcoVec) - Sparse deletions without reindexing
- Lightweight rollback without full snapshots
- Derived computations stored on disk (with
EagerVec)
Not ideal for:
- Heavy random write workloads
- Frequent insertions in the middle
- Variable-length data (strings, nested vectors)
- ACID transaction requirements
- Key-value lookups (use a proper key-value store)
Feature Flags
No features are enabled by default. Enable only what you need:
Available features:
pco- Pcodec compression support (PcoVec)zerocopy- Zero-copy mmap access (ZeroCopyVec)lz4- LZ4 compression support (LZ4Vec)zstd- Zstd compression support (ZstdVec)derive- Derive macros forBytesandPcotraitsserde- Serde serialization supportserde_json- JSON output using serde_jsonsonic-rs- Faster JSON using sonic-rs
With Pcodec compression:
With all compression formats:
Examples
Comprehensive examples in examples/:
zerocopy.rs- ZeroCopyVec with holes, updates, and rollbackpcodec.rs- PcoVec with compression
Run examples:
Performance
See vecdb_bench for detailed benchmarks.
vecdb is significantly faster than general-purpose embedded databases for fixed-size data workloads.