Key-Value Stores

Embedded and networked key-value stores, from LMDB and RocksDB to Redis and FoundationDB.

BadgerDB

BadgerDB is an embedded, persistent key-value store written in pure Go by the Dgraph team. Designed in 2017 to address the problem that LevelDB- and…

FoundationDB

FoundationDB is a distributed, ordered key-value store with strictly serializable multi-key ACID transactions, used as a foundation for higher-level data models.

LMDB (Lightning Memory-Mapped Database)

LMDB is an embedded, memory-mapped, B+tree key-value store written in C by Howard Chu of OpenLDAP. It is one of the fastest embedded databases ever built…

LevelDB

LevelDB is a fast, embedded key-value store written by Sandy Ghemawat and Jeff Dean at Google. It is a single-process library — no server, no network…

Memcached

Memcached is a high-performance, distributed in-memory key-value cache designed in 2003 by Brad Fitzpatrick at LiveJournal. It is the spiritual ancestor of…

Redis

Redis ( RE mote DI ctionary S erver) is the most-deployed NoSQL system in the world. Created by Salvatore Sanfilippo in 2009, it is an in-memory…

RocksDB

RocksDB is a high-performance embedded key-value database, originally forked from Google's LevelDB by Facebook (Meta) in 2012. It keeps LevelDB's LSM-

bbolt

bbolt is an embedded, pure-Go B+tree key-value store, originally written by Ben Johnson as BoltDB and now maintained by the etcd team as bbolt . It is to Go…

1. Overview

A key-value store maps opaque keys to opaque values and exposes a small API: get, put, delete, and in ordered stores, range scans by key prefix. That narrow interface is what makes them fast and composable; many larger databases are built on top of one. The eight stores in this section fall into two groups. Embedded stores (LevelDB, RocksDB, BadgerDB, LMDB, bbolt) are libraries linked into a single process with no server or network hop. Networked stores (Redis, Memcached, FoundationDB) run as servers shared by many clients, ranging from a pure cache to a distributed transactional database.

2. Families and storage engines

Key-Value Store Families Embedded LSMLevelDB, RocksDB, Badger Embedded B+treeLMDB, bbolt In-memory serverRedis, Memcached Distributed txnFoundationDB Embedded stores are libraries inside one process; servers are reached over the network. LSM trees favour write throughput; B+trees favour read latency and simple crash recovery.

Embedded stores differ mainly in their on-disk structure. LSM-tree engines (LevelDB, RocksDB, BadgerDB) append writes to a log and memtable and merge sorted files in the background, giving high write throughput at the cost of compaction work and some read amplification; BadgerDB separates large values from keys to reduce that cost. B+tree engines (LMDB, bbolt) update pages copy-on-write in a single file, which gives very fast reads, simple crash safety, and one writer at a time. Among servers, Memcached is a volatile cache with no persistence; Redis keeps data in memory with optional persistence and rich data structures; FoundationDB distributes an ordered key space across a cluster with serializable transactions.

3. When to use which

StoreTypeChoose it when
RedisIn-memory serverCaching, sessions, rate limits, queues, leaderboards with data structures
MemcachedIn-memory cacheSimple, multi-threaded look-aside cache with no persistence
RocksDBEmbedded LSM (C++)Write-heavy storage engine inside a larger system
LevelDBEmbedded LSM (C++)Small, simple embedded store; RocksDB is the usual upgrade
BadgerDBEmbedded LSM (Go)Go services needing fast writes without cgo
LMDBEmbedded B+tree (C)Read-heavy workloads, many readers, memory-mapped access
bboltEmbedded B+tree (Go)Go apps needing a simple transactional file store (etcd uses it)
FoundationDBDistributed ordered KVMulti-key ACID transactions across a cluster

4. Example: the same operations in two stores

# Redis: networked, with TTLs and atomic counters
redis-cli SET session:42 '{"user":"kevin"}' EX 3600
redis-cli INCR rate:ip:203.0.113.7
redis-cli GET session:42
# LMDB: embedded, transactional, ordered keys
import lmdb
env = lmdb.open("/tmp/kv-demo", map_size=10 * 2**20)
with env.begin(write=True) as txn:
    txn.put(b"user:001", b"alice")
    txn.put(b"user:002", b"bob")
with env.begin() as txn:
    cur = txn.cursor()
    cur.set_range(b"user:")          # ordered prefix scan
    for k, v in cur:
        if not k.startswith(b"user:"):
            break
        print(k, v)

The Redis example shows what networked stores add: expiry and atomic server-side operations shared by many clients. The LMDB example shows what embedded ordered stores add: transactions and range scans with no network hop.

5. Common pitfalls

See also wide-column stores.