Skip to main content

LMDB

LMDB (Lightning Memory-Mapped Database) is an embedded key–value store used by Kumo for transactional, high-performance local metadata and small control-plane data.

This page documents its performance characteristics, C++ API usage, and on-disk layout as they relate to Kumo.


1. Performance characteristics

LMDB is optimized for:

  • Fully ACID transactions
  • Memory-mapped I/O
  • Single-writer, multiple-reader concurrency
  • Ordered iteration by key

Typical characteristics (single node, SSD/NVMe storage):

MetricTypical range
Point lookup (Get)~1–20 µs
Sequential scanMemory bandwidth bound
Write throughput50–300 MB/s (single writer)
Read concurrencyUnlimited (multi-reader)
Memory usageMostly mapped file size + page cache
TIPS

LMDB maps the entire database into memory. For Kumo control-plane usage, the total dataset should typically not exceed 1–2 GB per node. Exceeding this may lead to memory pressure and slower writes.

LMDB is best suited for embedded workloads where:

  • Transactional guarantees are required
  • Reads dominate writes
  • Dataset fits comfortably in virtual memory

2. C++ API usage

Kumo uses the native LMDB C API via C++ wrappers.

Open an environment

#include <lmdb.h>

MDB_env* env;
int rc = mdb_env_create(&env);
mdb_env_set_maxdbs(env, 16);
mdb_env_set_mapsize(env, 1UL * 1024 * 1024 * 1024); // 1 GB
rc = mdb_env_open(env, "/data/kumo/lmdb", 0, 0664);

Begin a transaction

MDB_txn* txn;
rc = mdb_txn_begin(env, nullptr, 0, &txn); // 0 = read-write

Open a database

MDB_dbi dbi;
rc = mdb_dbi_open(txn, nullptr, 0, &dbi); // nullptr = default DB

Put (Set)

MDB_val key, data;
key.mv_size = strlen("key1");
key.mv_data = (void*)"key1";
data.mv_size = strlen("value1");
data.mv_data = (void*)"value1";

rc = mdb_put(txn, dbi, &key, &data, 0);

Get

MDB_val val;
rc = mdb_get(txn, dbi, &key, &val);
if (rc == 0) {
std::string value((char*)val.mv_data, val.mv_size);
}

Commit transaction

rc = mdb_txn_commit(txn);

Abort transaction

mdb_txn_abort(txn); // undo changes

Close database and environment

mdb_dbi_close(env, dbi);
mdb_env_close(env);

3. On-disk directory structure

A typical LMDB environment directory looks like:

/data/kumo/lmdb/
├── data.mdb
├── lock.mdb
FilePurpose
data.mdbMemory-mapped database file
lock.mdbLock file for single-writer concurrency

LMDB uses a memory-mapped file and keeps all B+ tree pages in memory. No background compaction is required. The database grows automatically but requires predefined map size.

Applications should treat the environment as opaque and avoid manual edits.


Summary

LMDB provides:

  • Embedded, memory-mapped KV interface
  • Full ACID transactions
  • Very low read latency and multi-reader concurrency
  • Simple, compact on-disk format

It is well suited for Kumo’s transactional local metadata and small control-plane datasets.