Build a Bitcask-style KV store
9 scenes · ~63 min · build the primitive

Build your own Bitcask-style KV store

The simplest possible KV store that still works: an append-only log on disk + an in-memory hash index. Build it from first principles and feel which trade-offs every later store inherits.

Scenes
9 interactive scenes
Time
about 63 minutes
Topic
Storage Engines & Databases

What you are building, and why

You are designing the simplest thing that could possibly work as a key-value store: clients send put(k, v) and get(k); the server appends each write to a log on disk and remembers where every live record is via a hash table in memory. That's it. There is no B-tree, no LSM, no skiplist, no MVCC, no compaction strategy beyond "rewrite the live records and atomically swap pointers."

Bitcask was Riak's local storage engine and is the canonical worked example of "what does the disk actually need to do?" Every later KV store — LevelDB, RocksDB, TiKV, FoundationDB, Pebble — is "Bitcask plus an answer to one of its limits." Once you have built Bitcask, the design space of every other embedded KV store collapses to a small set of named trades.

Resist the urge to "describe Bitcask." Make decisions yourself, defend them, and let the design push back. The point is to feel why each price is paid and which workload pays it.

What you will be able to explain afterwards

  • append-only log + in-memory hash (keydir)
  • single-writer write path
  • constant-time read path
  • RAM-per-key cost model
  • merge / compaction with atomic keydir swap
  • crash recovery + hint files
  • fsync trilemma (validity vs recency)
  • tombstone resurrection (riak_kv #925)
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 06a
  8. 07
  9. 08

Anatomy

Log on disk, hash in RAM — and the four-step write.

  1. 01
    Log on disk, hash in RAM
    A Bitcask is exactly two structures: an append-only log of records on disk + a single in-memory hash (the keydir). Every other property follows from this split.
    ~7 min
  2. 02
    Append, fsync, update, ack
    Every put is four ordered steps on one open writer. Concurrent writers are rejected at open(), not at write time.
    ~7 min
  3. 03
    One hash lookup, one pread
    get is a constant-time keydir lookup + at most one pread; bounded by one disk seek, zero when the page cache is hot.
    ~7 min

Limits

RAM is paid per key; merge gives back what's dead.

  1. 04
    RAM is paid per key, not per byte
    Every live key consumes a fixed-size keydir entry (~44.5 B + key length). RAM scales with key count alone — fat values are free, tiny tags OOM.
    ~7 min
  2. 05
    Merge — GC without stopping writes
    Merge scans only immutable files, writes a deduplicated copy, then atomically retargets keydir pointers. The active file is never touched.
    ~7 min

Crash & sync

Recovery, hint files, fsync — pick two.

  1. 06
    Crash recovery — scan or hint
    On startup the keydir is gone (RAM is gone). Hint files (a merge byproduct) drop cold-start time ~10x; per-record CRCs make a torn tail self-truncating.
    ~7 min
  2. 06a
    fsync — pick two of safe, fast, simple
    sync_strategy is a three-way trade (o_sync / interval / none). fsync controls RECENCY; CRC controls VALIDITY — two separate guarantees.
    ~7 min

Sharp edges

Tombstone resurrection and the design ceiling.

  1. 07
    Tombstones — deletes that come back
    If merge GCs a tombstone before every older segment containing the key has been merged away, restart resurrects the deleted key. The riak_kv #925 fix.
    ~7 min
  2. 08
    Design your KV — and feel its limits
    Capstone: every choice is a trade against the hash-in-RAM aesthetic. The absence of range/prefix iteration is the ceiling that bridges to LSM.
    ~7 min

Where you'll use this

Product designs whose trade-offs turn on what this curriculum teaches.

More in Storage Engines & Databases

Open the box every design diagram labels "DB": pages, logs, LSM trees, wide-column, documents, graphs and columnar scans, built from scratch.

Prefer to design it yourself?

The same subject as a staged workspace: draw the architecture, and a simulator traces requests through the boxes you drew.

Open the Build a Bitcask-style KV store workspace