Nothing gets lost
Kill it mid-write and restart. Everything you saved comes back, because it was written to disk before you were told it succeeded.
A database built from scratch in Rust. Every diagram on this page is live — click one and watch your data actually move through it.
Before a save counts as done, it is written down somewhere safe. So if the power goes out one second later, nothing is lost.
Press an action below and watch the path it takes.
Kill it mid-write and restart. Everything you saved comes back, because it was written to disk before you were told it succeeded.
Once a file is written it is never changed again. Cleaning up means merging old files into a new one and swapping it in.
Before reading a file it asks a tiny in-memory check that can say "definitely not in here" — so looking for something that isn't there is nearly free.
Every slice of your data lives on three machines. Lose one and the others keep answering without anyone noticing.
Data is split into chunks spread across machines. As a chunk fills up it splits in two, with nothing to rewrite and no downtime.
It speaks Postgres, so psql, your ORM and your existing app connect without
changing a line of code.
Every write is a sequential append to a write-ahead log that is fsynced before it is acknowledged, then inserted into a sorted in-memory memtable. A full memtable is flushed to an immutable SSTable; compaction merges those runs, keeps the newest version of each key and drops tombstones, writing to a temp file and renaming into place.
Reads check the memtable first, then SSTables newest-first, consulting a bloom filter per file to skip whole files without a disk seek. Each key range is its own Raft group of three replicas, placed by consistent hashing with virtual nodes, and ranges split and merge as they grow. The client protocol is the PostgreSQL wire protocol.
An AI assistant doesn't ask for one row. It asks for a hundred paragraphs at once, and it wants them in milliseconds. That changes what the database should be good at.
A search stack for a language model stores different things than one built for a human reader: not pages, but passages and the vectors computed from them. The read is a batch — give me these hundred keys, now — and the write is a bulk republish whenever a chunker or an embedding model changes.
The design splits those two jobs apart, the way Perplexity describes for CobbleDB: durable document state on cheap disk, batched partition-aligned delivery in between, and a hot store tuned for one operation — fetch these keys, fast.
Adding data and searching data want opposite things. Keeping them apart is the whole trick.
If a huge update writes straight into the thing answering searches, searches get slow. So updates go into a queue, and the search side picks them up when it has room.
Old and new versions sit side by side instead of overwriting. Switching is just pointing at the new one — and undoing it is pointing back.
A search result showing up a second late is fine; it doesn't need a bank's guarantees. Skipping the features it never uses is exactly what makes it fast.
Everything is kept on cheap disk. Only the part people actually search gets copied onto the expensive fast storage.
Type a question below. The page turns your words into numbers, compares them against a handful of sentences, and puts the closest ones on top. That's the whole idea behind search.
crashes when you type crash, but has no idea that
durable and fsync are related. A real AI model is the piece
that understands meaning — everything around it works exactly like this.
Words and character trigrams are signed-hashed into 64 dimensions and L2-normalised, then scored by cosine similarity — the same subword trick fastText uses, minus the learned weights. Swapping in a trained embedding model changes this one function and nothing else.
Drag the sliders to describe how much data you have and how busy you are. These are sums based on your numbers, not measurements — nothing here has been benchmarked yet.
every record, cheap tier
keys × record size
what the fleet must serve
the part cache does not absorb
working set at that hit rate
batched vs one get per key ·
Four ways in: the shell you already use, a command line, a Rust library you can drop into your own program, and a console right in the browser.
# start a node $ youdahedb-server --dir ./data --port 6380 # connect — psql muscle memory works $ youdahedb youdahedb=# \dt youdahedb=# select id, email from users limit 5; # one-shot, for scripts and CI $ youdahedb -c "select count(*) from orders" $ echo "select 1" | youdahedb
use youdahedb::LsmTree; let mut db = LsmTree::open("./data")?; db.put("user:1", "youdahe")?; let v = db.get("user:1")?; db.delete("user:1")?; // sorted iteration across memtable + every SSTable for (k, v) in db.scan("user:".."user;") { println!("{k} = {v}"); }
No libraries. Not one. Every piece is hand-written here, because the point is to understand how a database works — and you can't learn that from someone else's code.
Every B-tree, hash, file format, protocol parser and thread pool is implemented in this
repository. Cargo.toml has an empty [dependencies] section and it
stays that way.
The console runs a full SQL shell, schema browser, cluster view and live storage internals — no install.