Holt 0.3.2: an embedded persistent ART for path-shaped metadata
โ Rust ๐ 2026-05-23 ๐ค surdeus ๐๏ธ 1Hi Rustaceans,
I just released holt v0.3.2:
- GitHub: GitHub - feichai0017/holt: An adaptive-radix-tree metadata storage engine ยท GitHub
- crates.io: crates.io: Rust Package Registry
- docs.rs: holt - Rust
holt is an embedded Rust metadata engine built around a persistent Adaptive Radix Tree. It is designed for path-shaped metadata workloads: S3 object names, filesystem paths, namespace catalogs, artifact indexes, and similar hierarchical key spaces.
The main idea is that many metadata workloads are not random KV workloads. They are usually shaped like:
bucket/prefix/object/usr/local/share/filetenant/project/path/key
and the hot operations are not just get and put, but also prefix scans, delimiter rollups, conditional creates, atomic renames, and directory-style emptiness checks.
holt focuses on that shape directly.
What it supports today
The public API is intentionally small:
Tree::get,put,deleteTree::put_if_absentTree::compare_and_putTree::delete_if_versionTree::renameTree::atomicTree::rangeTree::scan_keysTree::view
The values are opaque bytes. Holt does not try to own your object metadata schema, inode format, protobuf layout, or JSON structure. The engine only owns the persistent path index and metadata operations.
A small example:
use holt::{TreeBuilder, WalCommit};
let tree = TreeBuilder::new("/tmp/meta.holt")
.wal_commit(WalCommit::Enqueue)
.open()?;
tree.put_if_absent(
b"bucket-a/photos/2026/img001.jpg",
b"{\"size\":12345,\"etag\":\"abc\"}",
)?;
for entry in tree.scan_keys(b"bucket-a/photos/").delimiter(b'/') {
println!("{:?}", entry?);
}
let record = tree.get_record(b"bucket-a/photos/2026/img001.jpg")?;
tree.compare_and_put(
b"bucket-a/photos/2026/img001.jpg",
record.version,
b"{\"size\":12345,\"etag\":\"def\"}",
)?;
Internals
The current design includes:
Persistent ART over 512 KiB blob frames
WAL with group commit
File-backed and in-memory modes
Per-blob latching inspired by LeanStore-style optimistic/shared/exclusive access
Prefix and delimiter-aware range iteration
Snapshot-style prefix views via Tree::view
SIMD-assisted hot paths where useful
Optional Linux io_uring backend for persistent I/O paths
A separate benchmark package comparing Holt with RocksDB, SQLite, and sled on metadata-shaped workloads
What it is good at
Holt is meant for embedded metadata-heavy systems:
object-store metadata
filesystem metadata indexes
lakehouse / artifact catalogs
path-based namespace catalogs
local metadata caches for remote storage
The benchmark suite includes kv, objstore, and fs workloads. The kv workload is intentionally included as an anti-pattern baseline. Holt is not trying to be a generic RocksDB replacement; the intended workload is hierarchical metadata with prefix/list/rename-style operations.
What it is not
Holt is currently:
pre-1.0
single-node
embedded only
Unix-only
not a network server
not a SQL engine
not a replicated database
not an MVCC OLTP engine
If you need consensus, replication, SQL, full-text, or vector search, those should live above or beside Holt.
Feedback wanted
I would especially appreciate feedback on:
Rust API shape
transaction / atomic batch semantics
iterator and snapshot-view semantics
persistence and WAL design
benchmark methodology
whether the crate boundary feels clean for real embedded use
Thanks!
1 post - 1 participant
๐ท๏ธ Rust_feed