A tiny, crash-tolerant key/value database written from scratch in pure Python (~350 lines). Built by hand as a learning project, following the classic "DBDB: Dog Bed Database" chapter by Taavi Burns from 500 Lines or Less.
It looks like a Python dictionary:
import dbdb
db = dbdb.connect("dogs.db") # open (or create) a database file
db["wangcai"] = "golden" # set
db.commit() # durably write to disk
print(db["wangcai"]) # get -> "golden"
db.close()…but underneath it implements the core mechanics of a real database engine:
- Append-only storage — data is never overwritten in place, so a crash can't corrupt committed data
- Immutable binary search tree with copy-on-write — every update creates new nodes along the path to the root; old trees stay intact on disk
- Atomic commits — a commit is a single 8-byte root-address write into the superblock: it either happens or it doesn't
- Lazy loading — nodes and values are read from disk only when followed, so the dataset can be larger than memory
- Multi-process safety — writers take an exclusive file lock; readers always see the last committed root
db = dbdb.connect("dogs.db")
db["a"] = "committed"
db.commit()
db["b"] = "uncommitted"
# 💥 process dies here — no commit, no close
db = dbdb.connect("dogs.db")
db["a"] # -> "committed" (still there)
"b" in db # -> False (vanished cleanly, no corruption)Because writes only append and the root address flips atomically, an interrupted write simply leaves unreachable garbage at the end of the file — the last committed tree is untouched.
Requires Python 3.8+. The only dependency is portalocker (cross-platform file locking).
git clone https://github.com/ChengyanOo/build-my-own-dog-bed-db-with-python.git
cd build-my-own-dog-bed-db-with-python
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtimport dbdb
db = dbdb.connect("example.db")
db["key"] = "value" # stage a write (takes the write lock)
db.commit() # make it durable (releases the lock)
value = db["key"] # read
"key" in db # membership test
len(db) # number of keys
del db["key"] # delete (needs a commit too)
db.close()python -m dbdb.tool example.db set greeting hello
python -m dbdb.tool example.db get greeting
python -m dbdb.tool example.db delete greetingExit codes: 0 OK, 1 bad arguments, 2 unknown command, 3 key not found.
The layers are stacked bottom-up, each one only talking to the layer below:
| Module | Layer | Responsibility |
|---|---|---|
dbdb/physical.py |
Physical | Storage: append-only file with a 4 KB superblock, length-prefixed records, exclusive locking |
dbdb/logical.py |
Logical | ValueRef (lazy disk pointer) and LogicalBase (get/set/pop/commit skeleton for any key/value structure) |
dbdb/binary_tree.py |
Data structure | Immutable BinaryNode, pickle-serialized BinaryNodeRef, copy-on-write BinaryTree |
dbdb/interface.py |
API | DBDB: the dict-like facade (__getitem__, __setitem__, __delitem__, …) |
dbdb/tool.py |
CLI | python -m dbdb.tool DBNAME get/set/delete … |
How a commit works:
- Every mutation builds new tree nodes in memory; nothing touches disk yet.
commit()serializes the new nodes and appends them to the file, children before parents (so every stored node only references already-stored addresses).- Finally the new root's address is written into the superblock at offset 0. That single write is the commit.
This is a teaching project; these gaps are kept intentionally, matching the book chapter:
- No
fsync— commitsflush()to the OS, so the process can crash safely, but a power failure can still corrupt the file. A production database mustos.fsync. - Pickle serialization — never open an untrusted
.dbfile; unpickling can execute arbitrary code. - Unbalanced tree — sequential inserts degrade to a linked list and hit
RecursionErroraround ~1000 keys. Balancing (e.g. a B-tree) is the book's suggested exercise. - String keys/values only — storing non-strings fails at read/commit time, not at assignment.
- Write lock is held until commit/close — a writer that never commits blocks all other writers indefinitely.
Original design and code: Taavi Burns, 500 Lines or Less — DBDB: Dog Bed Database (MIT licensed). This repository is my from-scratch reimplementation of it as a hands-on learning exercise. See LICENSE.