# libmdbx: embedded ACID storage with copy-on-write transactions

> libmdbx is a C library for applications that need an embedded, transactional key-value database across several processes. Its B+ tree, memory-mapped storage, MVCC, and serialized writers fit read-heavy local workloads, but the lack of WAL makes sync behavior and long readers important constraints.

**Mithril-mine/libmdbx** — Fastfull embedded transactional key-value storage engine ★ Surpasses the legendary LMDB in reliability, capabilities and performance ★ Used in hundreds of open source projects, including Ethereum.

- Repository: https://github.com/Mithril-mine/libmdbx
- Website: https://libmdbx.dqdkfa.ru
- Stars: 1,480 · Forks: 154
- Language: C
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/mithril-mine-libmdbx

## Why libmdbx targets embedded multi-process state

libmdbx addresses applications that keep their working data in a local file but need more consistency than a loose key-value cache. It supports several named key-value maps and multimaps within one data file, ACID transactions, and access by multiple processes and threads. The intended users are developers embedding a database directly into an application written in C or a language with access to its C API. There is no internal server thread and no database daemon.

This design is closest to applications that need transaction isolation while avoiding a separate service. The repository includes C and C++ examples plus a config-store example, although the README does not describe those examples in enough detail to reproduce their workflows here. It does establish that libmdbx implements the core of the Berkeley DB API and adds extensions. That distinction matters because adoption involves linking and managing an embedded engine rather than connecting to a networked database.

The data model remains deliberately narrow. Keys are sorted, records can be retrieved by key or scanned by range, and large native 32-bit and 64-bit integers have specific support. There are also duplicate-value structures for multimaps. libmdbx does not present itself as a relational database, document store, or distributed consensus system. It is for state that maps naturally to ordered keys and values.

## B+ tree pages, MVCC, and the single-writer path

libmdbx stores its B+ tree through a memory-mapped file. The README attributes `O(log N)` lookup, insertion, update, and deletion costs to the B+ tree structure. Records are accessible directly through the mapping, with zero-copy scanning documented for full in-memory traversal. Memory mapping does not mean that a transaction may modify mapped pages in place, because readers must retain a consistent snapshot.

Updates use copy-on-write. A writer creates replacement pages rather than overwriting pages that an existing reader may still need. Multi-version concurrency control supplies snapshot isolation, while serializability for writers comes from a single mutex. That produces a clear concurrency boundary: only one write transaction can be active at a time, but read and write transactions do not block each other. Parallel readers use the documented snapshot without atomic or interlocked operations in the read path.

The database also supports nested transactions, explicit and continuous defragmentation, automatic file-size adjustment, and an append operation for presorted bulk data. Online hot backup is listed among its features. The README does not expose the exact backup API or restore procedure, so those calls should be taken from the project's C API reference before a deployment relies on them.

## Building libmdbx with the repository Makefile

The README does not provide a short package-manager installation recipe. It does provide a thunk Makefile that delegates to GNU Make, and the repository Makefile explicitly says that GNU Make 3.80 or later is required. The repository also contains `CMakeLists.txt`, `conanfile.py`, and separate C and C++ examples, so build integration can differ from the default repository command.

The root Makefile exposes `all` as a target and forwards build requests to `GNUmakefile`. A first build can therefore begin with the default target. The command below does not install the library system-wide or create a package; it builds through the repository's own build files.

```bash
make all
```

A successful result is a set of build artifacts, but the README does not name their exact output paths or platform-specific extensions. It also does not specify the compiler flags, CMake options, Conan version, or installation prefix that a production project should use.

The first application-level use is available under `examples/example-mdbx.c` and `examples/example-mdbx.c++`. The README does not include either file's contents, so inventing an opening sequence, data directory, or API call would be misleading. Start with the matching example for the API being integrated and use the linked C or C++ API reference for exact return codes and lifecycle requirements. For system-wide installation, the root Makefile lists `install`, `install-no-strip`, `install-strip`, and `uninstall`, but the README does not provide the destination conventions.

## Shadow paging changes disk and transaction behavior

libmdbx deliberately omits both a write-ahead log and a transaction journal. Instead, it uses shadow paging, which can remove routine crash recovery and database maintenance from the operational model. The README states that data integrity is preserved after a crash unless integrity was explicitly neglected in favor of write performance.

That last qualification is important. Application developers must determine which durability controls they select and what their settings mean. The README does not document the exact C API for sync modes, so this article cannot recommend a particular flag or claim a particular number of acknowledged writes after power loss. A project with contractual durability requirements should verify those semantics against the API reference and its own failure model.

There is no concurrent writer queue with conflict detection. The single writer acts as the serialization point, which explains the absence of transaction conflicts and deadlocks among writers. It also means the library is a poor fit for an application that expects many processes to submit writes simultaneously. Parallel reads are the scalable side of the design; write concurrency is deliberately constrained.

## Long readers can increase file growth and degrade updates

Copy-on-write has a direct operational cost. A read transaction keeps old pages alive because they remain part of that reader's snapshot. If an update retires or frees pages while a long-running reader still references them, those pages cannot be recycled. The README warns that concurrent changes can enlarge the process working set, consume available free database space, make the database grow quickly, and reduce performance.

This is more specific than a general recommendation to keep transactions short. Transaction lifetime must be bounded by how quickly pages become reusable. A background scanner that keeps one snapshot open while another part of the application performs frequent updates can change the storage behavior even when its own read rate is modest. Batch iteration, monitoring, or export code therefore needs an explicit transaction boundary.

The maximum values are also page-size dependent. Map values may reach `2146435072` bytes, while multimap values are limited to roughly half a page: `2022` bytes with the default 4 KiB page or `32742` bytes with a 64 KiB page. Map keys have the same approximate half-page restriction. Page size must be a power of two from `256` to `65536` bytes, so schema and storage sizing are design inputs rather than deployment details that can be ignored.

## libmdbx versus a conventional server database

The practical alternative is a conventional transactional database server accessed through a client protocol. That approach adds process management and network transport, but its documentation and tooling often address query languages, remote concurrency, administration, replication, and network failure. libmdbx takes the opposite approach: a compact C library embedded into the application, ordered key access, a local mapped file, and no service process.

The difference is architectural rather than a simple feature comparison. libmdbx's single-writer model and memory-mapped pages are suited to local state shared by cooperating processes. A server database generally separates application code from storage and can serve clients that do not share a filesystem. The README does not claim that libmdbx provides a query planner, SQL interface, remote client protocol, or replication system, so those needs fall outside the documented feature set.

Storage media also matters. Its B+ tree performs mostly random page access, and the README says SSDs provide a substantial advantage over spinning disks for large databases. Networked or archival storage should not be assumed to behave like local attached storage. libmdbx is therefore a poor fit when the database must live on a remote filesystem designed for server access rather than direct local file use.

## Release activity, embedding cost, and Apache-2.0 obligations

The repository is not archived, and its last push was on 2026-10-15. Releases include `v0.14.4` on 2026-09-19, `v0.14.3` on 2026-08-09, and `v0.14.2` on 2026-05-14. These dates show recent repository and release activity, but they do not establish compatibility for every build target or remove the need to read each release's changes.

Embedding still carries integration cost. The C surface requires correct database and transaction lifecycle management, error handling, and decisions about page size, map layout, durability, and cleanup. The project includes testing, static-library, shared-library, and maintenance targets in its root Makefile, plus utility binaries such as `mdbx_chk`, `mdbx_copy`, `mdbx_dump`, and `mdbx_defrag`. The README does not explain when each maintenance utility is required or how it interacts with an active application.

The repository identifies `Apache-2.0` as its license and includes `LICENSE`, `NOTICE`, and `COPYRIGHT` files. Code distributed with those obligations must retain the applicable notices and license text. This is a compliance note rather than legal advice. The source layout also exposes the main implementation in `mdbx.c`, public headers such as `mdbx.h` and `mdbx.h++`, and C++ wrapper files, which is useful when reviewing what will actually be linked.

## Conclusion

Application teams should consider libmdbx when they can embed the storage engine directly and mainly need local ACID transactions, concurrent reads, range lookups, and multiple tables in one file. Server databases, networks, distributed replication, and write-intensive workloads with strict WAL-oriented durability should look elsewhere because they fall outside the documented design. Before adoption, verify the required build integration, shutdown and backup procedures on the target operating system, the effect of transaction duration on space reuse, and whether the documented durability mode matches the application's data-loss requirements.

## FAQ

### Does libmdbx use a write-ahead log?

No. It uses shadow paging instead of WAL or a transaction journal, so the README says it requires no routine crash recovery or database maintenance.

### Can multiple processes write to the same libmdbx database at once?

Multiple processes can access the database, but only one write transaction can be active at a time. Writers are serialized through a single mutex, while read and write transactions do not block one another.

### What build requirement does the repository state?

The root Makefile says GNU Make 3.80 or later is required. It forwards targets such as `all`, `libs`, `test`, and `install` to `GNUmakefile`.

### What should users know about long read transactions?

A read transaction prevents retired or freed pages from being recycled. The README warns that long-lived parallel readers can increase the working set, consume free space, accelerate database growth, and reduce performance.

### Which operating systems does libmdbx support?

The README lists Linux, Windows, MacOS, Harmony, Android, iOS, FreeBSD, DragonFly BSD, Solaris, OpenSolaris, OpenIndiana, NetBSD, OpenBSD, and POSIX.1-2008-compliant systems.

## Sources

- [License: Apache-2.0](https://github.com/Mithril-mine/libmdbx/blob/master/LICENSE)
- [Mithril-mine/libmdbx on GitHub](https://github.com/Mithril-mine/libmdbx)
- [Project website](https://libmdbx.dqdkfa.ru)
- [README](https://github.com/Mithril-mine/libmdbx/blob/master/README.md)
- [Releases](https://github.com/Mithril-mine/libmdbx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mithril-mine-libmdbx
