Mace
Mace is a high-performance, embedded key-value database written in Rust, combining the predictable read performance of B+ Trees with the write throughput of LSM Trees.
Key Features
- Hybrid Performance: B+ Tree-like read speeds with LSM-Tree-like write throughput.
- Concurrent MVCC: Non-blocking concurrent reads and writes with snapshot isolation.
- ACID Transactions: Crash-safe commit, abort, and recovery.
- Flash-Optimized: Log-structured design tailored for SSD/NVMe endurance.
- Large Value Separation: Large values live outside the index, cutting maintenance I/O.
- Merge Operators: Optional per-bucket operators support durable merge operands and reads.
- Optional Zstd Compression: Per-bucket
enable_compression(default:false). - Data Integrity: CRC checksums on persisted records, verified across restarts and crashes.
- Flow Control: Optional foreground write backpressure to bound memory growth.
- Cross-Platform: Linux, Windows, FreeBSD and macOS.
Quick Start
The following example demonstrates basic transaction management and data retrieval:
use ;
Additional runnable examples are available in the examples/ directory.
Benchmarks
Mace vs RocksDB on small values, relaxed durability (snapshot reads):
| Workload | Mace ops/s | RocksDB ops/s | mace/rocksdb ops | Mace p99 | RocksDB p99 |
|---|---|---|---|---|---|
| W1 (95% Read, 5% Update, 1 thread) | 541,950 | 281,074 | 1.93x | 4 | 8 |
| W1 (95% Read, 5% Update, 8 threads) | 2,941,301 | 1,100,399 | 2.67x | 8 | 16 |
| W2 (95% Read, 5% Update, zipf, 1 thread) | 1,314,220 | 824,557 | 1.59x | 2 | 4 |
| W2 (95% Read, 5% Update, zipf, 8 threads) | 4,156,555 | 1,442,814 | 2.88x | 4 | 16 |
| W3 (50% Read, 50% Update, 1 thread) | 265,720 | 184,274 | 1.44x | 4 | 8 |
| W3 (50% Read, 50% Update, 8 threads) | 1,306,037 | 662,721 | 1.97x | 8 | 16 |
| W4 (5% Read, 95% Update, 1 thread) | 177,297 | 157,432 | 1.13x | 8 | 8 |
| W4 (5% Read, 95% Update, 8 threads) | 707,002 | 473,584 | 1.49x | 16 | 16 |
| W5 (70% Read, 25% Update, 5% Scan, 1 thread) | 261,862 | 163,576 | 1.60x | 16 | 16 |
| W5 (70% Read, 25% Update, 5% Scan, 8 threads) | 1,475,692 | 729,926 | 2.02x | 16 | 32 |
| W6 (100% Scan, 1 thread) | 94,106 | 50,880 | 1.85x | 8 | 16 |
| W6 (100% Scan, 8 threads) | 460,125 | 284,069 | 1.62x | 16 | 32 |
Dataset: 16B key / 128B value, 1M keys, relaxed durability, snapshot reads.
Merge-operator workloads — u64 counter: merge (+1) vs get, fixed 8-byte values, 32-byte keys:
| Workload | Mace ops/s | RocksDB ops/s | mace/rocksdb ops | Mace p99 | RocksDB p99 |
|---|---|---|---|---|---|
| MERGE_70 (30% get, 70% merge), 1 thread | 210,386 | 253,281 | 0.83x | 4 | 8 |
| MERGE_70 (30% get, 70% merge), 8 threads | 1,085,001 | 524,390 | 2.07x | 8 | 16 |
| MERGE_100 (100% merge), 1 thread | 192,250 | 282,164 | 0.68x | 8 | 4 |
| MERGE_100 (100% merge), 8 threads | 842,411 | 418,602 | 2.01x | 8 | 16 |
| MERGE_GET_0 (get after 0 merges/key), 1 thread | 3,867,072 | 2,009,637 | 1.92x | 1 | 1 |
| MERGE_GET_0 (get after 0 merges/key), 8 threads | 7,981,551 | 1,472,972 | 5.42x | 1 | 16 |
| MERGE_GET_1000 (get after 1k merges/key), 1 thread | 1,806,531 | 29,866 | 60.49x | 2 | 32 |
| MERGE_GET_1000 (get after 1k merges/key), 8 threads | 4,038,680 | 180,538 | 22.37x | 32 | 64 |
| MERGE_GET_10000 (get after 10k merges/key), 1 thread | 826,647 | 123,659 | 6.68x | 64 | 256 |
| MERGE_GET_10000 (get after 10k merges/key), 8 threads | 2,595,502 | 764,122 | 3.40x | 128 | 128 |
ops/s = successful operations per second (higher is better); p99 = 99th-percentile latency in µs (lower is better). Bold marks the best value per row.
These tables cover small-value workloads; results for larger values and write-heavy workloads can differ, and the full sweep — all value sizes, thread counts 1/2/4/8, and merge operators — is in the latest full results below.
Latest full results: https://abbycin.github.io/kv_bench/index.html
Methodology and comparison with other engines: kv_bench.
Design Notes
Architecture and crash-safety notes are in docs/design.md.
Status
Storage format and public APIs are essentially stable and ready for production evaluation. Breaking format changes will ship with a migration path rather than silently.
Discussion
Use GitHub Discussions for questions and design talk, or open an issue for bugs and feature requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.