Skip to main content

Project: Key-Value Store

Build a production-quality key-value store with persistence, memory management, and basic indexing. This project teaches file I/O, data structures, and systems design. This is one of the most instructive systems projects you can build because it sits at the intersection of nearly every systems programming topic: hash tables for fast lookups, file I/O for persistence, binary serialization for the on-disk format, write-ahead logging for crash safety, and reader-writer locks for concurrent access. Redis, LevelDB, and RocksDB all started from fundamentally the same building blocks you will implement here.

Features

1

In-Memory Storage

Hash table for fast O(1) lookups
2

Persistence

Write-ahead log and snapshots
3

Variable-Size Values

Store arbitrary binary data
4

Concurrent Access

Thread-safe operations

Data Structures

The architecture mirrors what real databases use at a simplified scale. Think of it as a library system: the hash table is the card catalog (fast lookup by title), each bucket’s linked list handles collisions (multiple books filed under the same catalog number), the write-ahead log is the librarian’s notebook (recording every checkout and return before updating the card catalog, so nothing is lost if the power goes out), and the snapshot is a complete photocopy of the catalog at a point in time.

Hash Table Implementation


Core Operations


Persistence

The database needs two persistence mechanisms working together:
  1. Write-Ahead Log (WAL): Every mutation (put/delete) is appended to a log file before modifying the in-memory hash table. If the process crashes, the WAL can be replayed to recover all operations since the last snapshot. This is the same approach used by PostgreSQL, SQLite, and virtually every production database.
  2. Snapshots: Periodically, the entire hash table is written to a single file. After a successful snapshot, the WAL is truncated. Snapshots are written to a temporary file first, then atomically renamed — this ensures that a crash during snapshot writing does not corrupt the existing snapshot.
The combination means: snapshots provide fast recovery (load one file), and the WAL provides durability between snapshots (replay a short log).

CLI Interface


Extensions

TTL/Expiration

Add automatic key expiration

Transactions

Implement MULTI/EXEC transactions

Replication

Add master-slave replication

Compression

Compress values with LZ4 or zstd

Binary Protocol

Add a Redis-like binary protocol

Cluster Mode

Shard data across nodes

Next Up

Build a Memory Allocator

Implement your own malloc