---
title: "We are replacing RocksDB with SurrealKV 1.0"
description: "SurrealKV 1.0 is open source today: 7.95× faster point reads than RocksDB with synchronous durability, and the command to run the benchmark yourself."
url: https://surrealdb.com/blog/we-are-replacing-rocksdb-with-surrealkv-1-0
date: 2026-10-13
authors: "Tobie Morgan Hitchcock"
---

# We are replacing RocksDB with SurrealKV 1.0

![We are replacing RocksDB with SurrealKV 1.0](https://cdn.surrealdb.com/0ytqbh70mi5w5xl6lh1nban7.auto)

SurrealKV 1.0 is a new open source persistent storage engine for SurrealDB, written in Rust and released under Apache 2.0 on 13 October 2026. With synchronous durability, it reads 7.95× faster than RocksDB and 73.7× faster than SlateDB, and it will be the only persistent storage engine in SurrealDB 4.

## Why replace RocksDB?

RocksDB is a very good engine, and SurrealDB has run on it for years. It is also a large C++ library that SurrealDB does not control. SurrealKV is an engine we can read from end to end, change when SurrealDB needs it to change, and ship as a Rust crate.

SurrealKV is a log-structured merge-tree with snapshot-isolated transactions. It runs embedded in an application and as the storage layer of a SurrealDB server.

## How does SurrealKV reach these numbers?

Three design decisions each remove shared work or shared waiting from a hot path.

- **A radix-tree memtable.** Writes land in a concurrent adaptive radix tree allocated from a fixed arena. RocksDB and Pebble use skiplists.
- **A commit ring.** Many committers validate their transactions at the same time. One flusher task then orders what has accumulated into a group, appends it to the write-ahead log with at most one fsync, applies it to the memtable and publishes it. A burst of commits costs one log append.
- **Cheap reads.** A read pins a sequence number and nothing else.

## What else does SurrealKV include?

- **Versioned trees**, opt in. `get_at` reads a key as of a time, `history` returns every version of a key, and compaction keeps versions for a retention period that you set.
- **Value separation**, opt in, for values larger than 1 KiB, so that compaction does not rewrite large values again and again.
- **Encryption at rest**, transparent, with AES-256-GCM or XChaCha20-Poly1305.
- **Differential testing** against an in-memory reference model: 500 seeds of 5,000 steps each, 2,500,000 operations, in every CI run. Any divergence fails the run.

## What do the benchmarks show?

With synchronous durability, every commit is flushed to disk before it returns. SurrealKV 1.0 delivered these results on 13 October 2026:

| Engine | Point reads (OPS) | Creates (OPS) | Updates (OPS) | Deletes (OPS) | Scans (OPS) |
|---|---:|---:|---:|---:|---:|
| **SurrealKV** | **6,804,864** | **229,376** | **221,341** | **264,089** | **905,132** |
| RocksDB | 855,851 | 8,568 | 36,263 | 32,043 | 852,661 |
| SlateDB | 92,303 | 8,257 | 8,122 | 8,242 | 17,985 |

Against RocksDB, SurrealKV is 7.95× faster on point reads, 6.10× faster on updates, 8.24× faster on deletes and 1.06× faster on range scans. Against SlateDB, which ran on local disk and not on object storage, it is 73.7× faster on point reads and 27.3× faster on updates.

SurrealKV creates records 26.8× faster than RocksDB. RocksDB's create rate with synchronous durability is far below its own update rate of 36,263 operations a second, and we have not explained why, so this post does not headline it.

The benchmark ran with [crud-bench](https://github.com/surrealdb/crud-bench) on an AMD Ryzen Threadripper 9970X (32 cores, 64 threads) with 128 GB of RAM and a 4 TB NVMe SSD. It used 500,000 keys, 48 worker threads and 128 clients. The harness runs SurrealKV with value separation on and a larger memtable than the engine's defaults. Each figure is a single run. Fjall, ReDB, LMDB and libmdbx are not in the table, because their runs with synchronous durability were too slow to finish at this dataset size.

## Where is RocksDB faster?

Without synchronous durability, RocksDB is faster at writes. SurrealKV is 1.88× slower on creates, 2.22× slower on updates and 2.41× slower on deletes, and 8.26× faster on point reads.

Without synchronous durability, the engines also make different promises about what survives a crash, so those figures measure speed and not safety. Only the synchronous-durability table compares engines that each flush before acknowledging.

## How do range scans compare?

Without synchronous durability, SurrealKV scans the first 100 key-value pairs of the dataset 896,366 times a second. LMDB leads that scan at 1,192,772 scans a second, and RocksDB manages 851,848. The table shows scans per second over the same 500,000 keys, with 5,000,000 iterations of each scan.

| Engine | Limit (OPS) | Keys, limit (OPS) | Skip + limit (OPS) | Keys, skip + limit (OPS) | Full count (OPS) |
|---|---:|---:|---:|---:|---:|
| **SurrealKV** | 896,366 | **2,313,942** | 96,365 | 98,612 | 402 |
| RocksDB | 851,848 | 851,580 | 35,539 | 35,902 | 159 |
| SlateDB | 26,187 | 26,266 | 7,460 | 7,477 | 87 |
| Fjall | 132,698 | 151,861 | 4,335 | 4,383 | 42.4 |
| ReDB | 561,837 | 571,629 | 44,438 | 44,462 | 249 |
| LMDB | **1,192,772** | 1,195,166 | **549,220** | **552,090** | **902** |
| libmdbx | 384,128 | 260,769 | 183,361 | 185,073 | 848 |

- **Limit** (`select(*) limit(100)`) returns the first 100 key-value pairs of the range. **Keys, limit** (`select(id) limit(100)`) returns only the keys.
- **Skip + limit** (`select(*) start(5000) limit(100)`) walks and discards 5,000 entries before returning 100. **Keys, skip + limit** returns only the keys.
- **Full count** (`count()`) visits every key in the range.

Against RocksDB, SurrealKV is 1.05× faster on the first 100 pairs, 2.72× faster on a keys-only scan of the first 100 entries, 2.71× faster on scans that skip 5,000 entries and 2.53× faster on full counts. SurrealKV leads every engine on the keys-only scan, at 2,313,942 scans a second.

LMDB leads SurrealKV on the first 100 key-value pairs (1.33× faster), on scans that skip 5,000 entries (5.70× faster) and on full counts (2.24× faster).

## How much memory does SurrealKV use?

SurrealKV has the lowest resting memory of the seven engines measured, at 221 MiB, against 590 MiB for RocksDB. Resting and peak memory are the lowest and highest process memory sampled across the whole benchmark run, without synchronous durability.

| Engine | Resting memory | Peak memory |
|---|---:|---:|
| **SurrealKV** | **221 MiB** | 1.79 GiB |
| RocksDB | 590 MiB | 1.02 GiB |
| SlateDB | 265 MiB | 2.73 GiB |
| Fjall | 627 MiB | 1.71 GiB |
| ReDB | 257 MiB | 2.17 GiB |
| LMDB | 776 MiB | **826 MiB** |
| libmdbx | 40.98 GiB | 117.71 GiB |

SurrealKV's peak memory of 1.79 GiB is higher than that of RocksDB (1.02 GiB) and LMDB (826 MiB), because parallel commits buffer active batches. The libmdbx figures are what the harness measured, and we have not investigated them.

## Where is the design written down?

The [SurrealKV whitepaper](https://surrealdb.com/static/whitepapers/surrealkv.pdf), "A Versioned LSM Engine with Radix-Tree Memtables and a Commit Ring", explains how SurrealKV reaches these numbers, what each design decision costs and what the measurements do not cover.

## How can you run the benchmark yourself?

Every figure comes from one command on one machine. Run it on your own hardware:

```bash
CRUD_BENCH_CONFIG=config/memory.toml ./run.sh -d surrealkv --no-build --optimised --sync -s 500000 -c 128 -t 48
```

Change the `-d` flag to run a comparator, and remove `--sync` to run without synchronous durability. If you find a fairer configuration for a comparator, open an issue or a pull request on the [crud-bench repository](https://github.com/surrealdb/crud-bench).

SurrealKV is open source on [GitHub](https://github.com/surrealdb/surrealkv). To use it in a Rust project, add the crate:

```bash
cargo add surrealkv
```

Speed or durability? Yes. Stop choosing.
