Flint logo

A key-value store, not a server to run

The SQLite of
key-value stores.

Flint is an embedded, single-binary key-value store: a persistent append-only log with an in-memory index. Point it at a directory and get a durable, crash-safe store that is instantly fast. No server, no JVM, no cluster.

See the log, live View on GitHub

Watch it work

A write appends. A read is one seek. Compaction reclaims.

This is the real model running in your browser: every write appends a record to the log, the in-memory index points at the latest one, and compaction rewrites only the live keys.

Append-only log

In-memory index (keydir)

How to use this playground
Type a command like SET user alice, GET user, or DEL user in the box and hit Run (or Enter); the sample chips fill it in for you. Watch each write append a record to the append-only log on the left while the in-memory index on the right points at the latest value. Hit Compact to merge the live keys into a fresh segment and reclaim stale space, and Reset to start over. It is the same log-and-keydir model as the Rust engine, running in your browser.

The same store from your shell

One binary. Set, get, delete, compact.

Real output from the release binary. A write is durable when the command returns, so no daemon has to be running first.

# set, overwrite, read the latest value, delete, reclaim space
$ flint --dir ./data set greeting "hello world"
OK
$ flint --dir ./data set user alice
OK
$ flint --dir ./data set user bob
OK
$ flint --dir ./data get user
bob
$ flint --dir ./data del greeting
1
$ flint --dir ./data compact
OK

Bitcask, in one directory.

One append-only log per store, one hash map holding the latest offset for every live key.

Append-only log

Every write appends a CRC-checked record to the active segment. When it passes its size cap, it rolls to a new file. Old data is never moved.

In-memory index

A hash map from each key to the file and byte offset of its latest value. That is why reads are one seek and writes are cheap.

Crash safety

Each record carries a CRC32. On open, Flint replays the log and stops a segment at the first torn or corrupt record, discarding a half-written trailing write.

Compaction

Merges the live keys into one fresh segment and deletes the old ones, reclaiming the space held by overwritten versions and tombstones.

Library, server, CLI, and persistent memory.

One binary, four ways to reach it.

Rust library

Store::open(dir, cap) then set / get / delete / compact. Keys and values are arbitrary bytes.

TCP server

flint serve speaks a tiny line protocol any client can use, even netcat. A background thread compacts as segments accumulate.

CLI

flint set greeting "hello", flint get greeting. One binary, one directory.

MCP server

flint mcp exposes durable scratch memory over the Model Context Protocol: flint_set, flint_get, flint_delete that survive across sessions.

Why not just Redis or SQLite?

Three shapes of storage, and where Flint fits between them.

vs Redis

Redis is a dedicated server with persistence tuning and cluster management. Flint is a library and a directory, with nothing to operate for the single-node embedded case.

vs SQLite

SQLite is a superb relational engine. When all you need is durable key to value, Flint is that shape directly: a log and a hash index, no SQL layer.

vs a plain file

A hand-rolled JSON file is not crash-safe and rewrites everything on each change. Flint appends, indexes in memory, and survives torn writes.