All work

Engineering · Rust · 2026

SlimDB

A crash-safe embedded database in Rust. No server, no configuration, no SQL. It replaces your save.json with a real database you never have to run.

Role
Solo: design and engineering
Stack
Rust · C ABI · Python
Proof
A kill -9 loop, 200,000 times a night
Links
GitHub

The problem

JSON files are fine until a kill -9 or a power cut lands in the middle of a write. Games, command-line tools and desktop apps keep their state in files that can be half-written at the worst possible moment, and nothing tells you until the next launch.

The design

A database is two files: a snapshot, game.sdb, and an append-only write-ahead log, game.sdb-wal. Every mutation goes to the log and is flushed to disk before the call returns, so anything acknowledged survives. Values are typed, from null to nested objects, and addressed by path: player.inventory.sword is a key, not a parsing job.

let mut db = Db::open("game.sdb")?;
db.set("player.level", Value::Int(42))?;
db.set("player.name", Value::Str("Aurel".into()))?;
assert_eq!(db.get("player.level")?, Some(Value::Int(42)));
db.close()?;

Crash recovery

On open, the log is replayed. Every record is framed and checked with CRC-32, so a write torn by a crash fails its checksum and is truncated, while everything before it is kept. Corruption in the middle of the file is a different case: it raises a loud error instead of being silently cut away.

Compaction folds the log into a fresh snapshot, and the snapshot is only ever replaced atomically: write to a temporary file, flush, rename. A .sdb file that exists is never partially written.

Proving it

The signature test is a kill loop: random writes, a random SIGKILL, reopen, and the state must match exactly what was committed. Every push runs 200 iterations, a nightly job runs 200,000, and a torn-write fuzzer runs in-process alongside it.

Bindings

Every binding sits on a C ABI, never on the core’s internals. Python goes through PyO3 on top of that ABI, so a new language costs one thin layer instead of a second implementation.

Scope, and what comes next

It is built for local, single-process apps: under 100,000 documents and under a gigabyte. Not a server, not distributed. Next on the roadmap are Node through N-API and Godot through GDExtension, so a game can save its state the same way.