Rollblock
A super-fast, block-oriented and rollbackable key-value store.
⚡ Super Fast — The entire dataset lives in RAM. Under the hood, hashbrown's RawTable delivers O(1) reads and writes with minimal overhead. On an Apple M4, Rollblock sustains ~1.4M ops/sec—35× faster than LMDB.
📦 Block-Oriented — Every mutation belongs to a block identified by a BlockId. When you commit, all operations succeed together or fail together. No partial state, no corruption—like SQL transactions, but designed for sequential workflows.
⏪ Rollbackable — An undo journal on disk lets you rewind to any previous state with a single call. Whether you roll back one block or a thousand, the store returns to that exact point in time: store.rollback(height)?
Built for blockchain nodes, event sourcing, game state, and any system that needs atomic commits with time-travel capabilities.
Documentation
- Architecture — Internal design, data flow, and component overview
- Configuration — All settings, durability modes, and tuning options
- Examples — Annotated code samples for common use cases
- Observability — Metrics, health checks, and monitoring integration
- Benchmark — Performance methodology and results
Install
Add rollblock to your Cargo.toml:
[]
= "0.3"
To use a specific key size, enable a feature:
[]
= { = "0.3", = ["key-32"] }
Available features: key-8 through key-64 (one per byte).
For custom sizes, set ROLLBLOCK_KEY_BYTES=64 cargo build (any value from 8 to 64).
Quick Examples
Server: Read & Write Operations
use ;
use ;
Client: Remote Reads via Socket
Rollblock includes an embedded TCP server for read-only remote access. The client is zero-allocation and speaks a compact binary protocol.
use Duration;
use ;
use BasicAuthConfig;
use StoreKey as Key;
To enable the server on the writer side:
use RemoteServerSettings;
let settings = default
.with_bind_address
.with_basic_auth;
let config = new?
.with_remote_server;
Configuration
| Parameter | Default | Description |
|---|---|---|
data_dir |
— | Base directory for metadata, journal, and snapshots |
shards |
— | Number of in-memory shards (4–16 recommended) |
thread_count |
1 |
Set to >1 to enable parallel execution via Rayon |
compress_journal |
false |
Enable zstd compression for the undo journal |
min_rollback_window |
100 |
Minimum number of blocks retained for rollback |
lmdb_map_size |
2 GB | LMDB metadata size (increase for high-frequency chains) |
Durability Modes
use DurabilityMode;
// Async (default): fast, acknowledges before fsync
let config = config.with_durability_mode;
// Synchronous: fsync after every block (slower but safer)
let config = config.with_durability_mode;
Key Size Configuration
The key size is fixed at compile time. Two methods are available:
Method 1: Cargo feature (recommended for libraries)
# In your Cargo.toml
[]
= { = "0.3", = ["key-32"] }
Available features: key-8 through key-64 (one per byte).
Method 2: Environment variable (for custom sizes)
ROLLBLOCK_KEY_BYTES=64
Any value between 8 and 64 is accepted.
Priority: Feature > Environment variable > Default (8 bytes).
⚠️ Only one
key-XXfeature can be active at a time. Server and client must use the same key size.
Data Model
| Type | Definition | Notes |
|---|---|---|
Key |
Key<const N> (default N = 8) |
Fixed-size identifier; width is fixed at compile time for a given build. |
Value |
Vec<u8> |
Up to 65,535 bytes. An empty value represents a deletion. |
BlockId |
u64 |
Block height. Must be strictly increasing. |
Operation |
{ key, value } |
A single mutation within a block. |
Keys are sharded using xxh3 over the key bytes: shard = xxh3_64(key) % shard_count. Design your key space accordingly for even distribution.
Choosing the key width: Use a Cargo feature (
key-8throughkey-64) or setROLLBLOCK_KEY_BYTESat build time. Both server and client builds must use the same width and data directories must be recreated after changing it. See Key Size Configuration below.
Limitations
Rollblock makes deliberate trade-offs. Know them before you commit:
| Limitation | Implication |
|---|---|
| Full in-RAM | Your dataset must fit in memory. OS swap will kill performance. |
| Single writer | Only one process can open a data directory at a time. |
| Read-only clients | The remote protocol only supports GET operations. All writes go through the primary. |
| Fixed key size per deployment | Key width is a compile-time constant (8-64 bytes). Changing it requires rebuilding the client/server and recreating data. The remote protocol advertises the width during handshake. |
| Value size cap | Maximum 65,535 bytes per value. |
Running the Examples
# Basic CRUD operations
# Chain reorganization simulation
# Parallel processing (release mode recommended)
# Remote client/server demo
# Metrics and health monitoring
Examples store data in ./data/. Clean up with:
License
Licensed under either of MIT or Apache-2.0 at your option.