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
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;
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;
Data Model
| Type | Definition | Notes |
|---|---|---|
Key |
[u8; 8] |
Fixed 8-byte identifier. Hash your keys upstream if needed. |
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 their raw bytes interpreted as little-endian u64: shard = key_as_u64 % shard_count. Design your key space accordingly for even distribution.
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 | Keys are exactly 8 bytes. Hash or truncate larger identifiers. |
| 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.