{"id":19348588,"url":"https://github.com/isar/libmdbx","last_synced_at":"2026-03-06T11:01:26.164Z","repository":{"id":40646940,"uuid":"484746836","full_name":"isar/libmdbx","owner":"isar","description":"Mirror of the libmdbx repository","archived":false,"fork":false,"pushed_at":"2025-11-19T16:39:48.000Z","size":10458,"stargazers_count":23,"open_issues_count":0,"forks_count":11,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-19T18:20:04.508Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://libmdbx.dqdkfa.ru","language":"C","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/isar.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog-01.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":"COPYRIGHT","agents":null,"dco":null,"cla":null}},"created_at":"2022-04-23T12:53:27.000Z","updated_at":"2025-11-12T18:39:31.000Z","dependencies_parsed_at":"2023-10-23T15:25:30.818Z","dependency_job_id":"7d553b07-bd9c-4385-b3ab-9daffa155024","html_url":"https://github.com/isar/libmdbx","commit_stats":null,"previous_names":[],"tags_count":80,"template":false,"template_full_name":null,"purl":"pkg:github/isar/libmdbx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isar%2Flibmdbx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isar%2Flibmdbx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isar%2Flibmdbx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isar%2Flibmdbx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/isar","download_url":"https://codeload.github.com/isar/libmdbx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isar%2Flibmdbx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30173345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T04:21:44.017Z","updated_at":"2026-03-06T11:01:26.153Z","avatar_url":"https://github.com/isar.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Required extensions: pymdownx.betterem, pymdownx.tilde, pymdownx.emoji, pymdownx.tasklist, pymdownx.superfences --\u003e\n\nlibmdbx\n=======\n\n\u003c!-- section-begin overview --\u003e\n\n_libmdbx_ is an extremely fast, compact, powerful, embedded, transactional\n[key-value database](https://en.wikipedia.org/wiki/Key-value_database),\nwith [Apache 2.0 license](https://gitflic.ru/project/erthink/libmdbx/blob?file=LICENSE).\n_libmdbx_ has a specific set of properties and capabilities,\nfocused on creating unique lightweight solutions.\n\n1. Allows **a swarm of multi-threaded processes to\n[ACID](https://en.wikipedia.org/wiki/ACID)ly read and update** several\nkey-value [maps](https://en.wikipedia.org/wiki/Associative_array) and\n[multimaps](https://en.wikipedia.org/wiki/Multimap) in a locally-shared\ndatabase.\n\n2. Provides **extraordinary performance**, minimal overhead through\n[Memory-Mapping](https://en.wikipedia.org/wiki/Memory-mapped_file) and\n`Olog(N)` operations costs by virtue of [B+\ntree](https://en.wikipedia.org/wiki/B%2B_tree).\n\n3. Requires **no maintenance and no crash recovery** since it doesn't use\n[WAL](https://en.wikipedia.org/wiki/Write-ahead_logging), but that might\nbe a caveat for write-intensive workloads with durability requirements.\n\n4. Enforces [serializability](https://en.wikipedia.org/wiki/Serializability) for\nwriters just by single\n[mutex](https://en.wikipedia.org/wiki/Mutual_exclusion) and affords\n[wait-free](https://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom)\nfor parallel readers without atomic/interlocked operations, while\n**writing and reading transactions do not block each other**.\n\n5. **Guarantee data integrity** after crash unless this was explicitly\nneglected in favour of write performance.\n\n6. Supports Linux, Windows, MacOS, Android, iOS, FreeBSD, DragonFly, Solaris,\nOpenSolaris, OpenIndiana, NetBSD, OpenBSD and other systems compliant with\n**POSIX.1-2008**.\n\n7. **Compact and friendly for fully embedding**. Only ≈25KLOC of `C11`,\n≈64K x86 binary code of core, no internal threads neither server process(es),\nbut implements a simplified variant of the [Berkeley\nDB](https://en.wikipedia.org/wiki/Berkeley_DB) and\n[dbm](https://en.wikipedia.org/wiki/DBM_(computing)) API.\n\n\u003c!-- section-end --\u003e\n\nHistorically, _libmdbx_ is a deeply revised and extended descendant of the legendary\n[Lightning Memory-Mapped Database](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database).\n_libmdbx_ inherits all benefits from _LMDB_, but resolves some issues and adds [a set of improvements](#improvements-beyond-lmdb).\n\n[![Telergam: Support | Discussions | News](https://img.shields.io/endpoint?color=scarlet\u0026logo=telegram\u0026label=Support%20%7C%20Discussions%20%7C%20News\u0026url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Flibmdbx)](https://t.me/libmdbx)\n\n\u003e Please refer to the online [official libmdbx documentation site](https://libmdbx.dqdkfa.ru)\n\u003e with [`C` API description](https://libmdbx.dqdkfa.ru/group__c__api.html)\n\u003e and pay attention to the [`C++` API](https://gitflic.ru/project/erthink/libmdbx/blob?file=mdbx.h%2B%2B#line-num-1).\n\u003e Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`.\n\u003e Всё будет хорошо!\n\nTelegram Group archive: [1](https://libmdbx.dqdkfa.ru/tg-archive/messages1.html),\n[2](https://libmdbx.dqdkfa.ru/tg-archive/messages2.html), [3](https://libmdbx.dqdkfa.ru/tg-archive/messages3.html), [4](https://libmdbx.dqdkfa.ru/tg-archive/messages4.html),\n[5](https://libmdbx.dqdkfa.ru/tg-archive/messages5.html), [6](https://libmdbx.dqdkfa.ru/tg-archive/messages6.html), [7](https://libmdbx.dqdkfa.ru/tg-archive/messages7.html).\n\n## Github\n\n### на Русском (мой родной язык)\n\nВесной 2022, без каких-либо предупреждений или пояснений, администрация\nGithub удалила мой аккаунт и все проекты. Через несколько месяцев, без\nкакого-либо моего участия или уведомления, проекты были\nвосстановлены/открыты в статусе \"public read-only archive\" из какой-то\nнеполноценной резервной копии. Эти действия Github я расцениваю как\nзлонамеренный саботаж, а сам сервис Github считаю навсегда утратившим\nкакое-либо доверие.\n\nВследствие произошедшего, никогда и ни при каких условиях, я не буду\nразмещать на Github первоисточники (aka origins) моих проектов, либо\nкак-либо полагаться на инфраструктуру Github.\n\nТем не менее, понимая что пользователям моих проектов удобнее получать к\nним доступ именно на Github, я не хочу ограничивать их свободу или\nсоздавать неудобство, и поэтому размещаю на Github зеркала (aka mirrors)\nрепозиториев моих проектов. При этом ещё раз акцентирую внимание, что\nэто только зеркала, которые могут быть заморожены, заблокированы или\nудалены в любой момент, как это уже было в 2022.\n\n### in English\n\nIn the spring of 2022, without any warnings or explanations, the Github\nadministration deleted my account and all projects. A few months later,\nwithout any involvement or notification from me, the projects were\nrestored/opened in the \"public read-only archive\" status from some kind\nof incomplete backup. I regard these actions of Github as malicious\nsabotage, and I consider the Github service itself to have lost any\ntrust forever.\n\nAs a result of what has happened, I will never, under any circumstances,\npost the primary sources (aka origins) of my projects on Github, or rely\nin any way on the Github infrastructure.\n\nNevertheless, realizing that it is more convenient for users of my\nprojects to access them on Github, I do not want to restrict their\nfreedom or create inconvenience, and therefore I place mirrors of my\nproject repositories on Github. At the same time, I would like to\nemphasize once again that these are only mirrors that can be frozen,\nblocked or deleted at any time, as was the case in 2022.\n\n## MithrilDB and Future\n\n\u003c!-- section-begin mithril --\u003e\n\nThe next version is under non-public development from scratch and will be\nreleased as **MithrilDB** and `libmithrildb` for libraries \u0026 packages.\nAdmittedly mythical [Mithril](https://en.wikipedia.org/wiki/Mithril) is\nresembling silver but being stronger and lighter than steel. Therefore\n_MithrilDB_ is a rightly relevant name.\n\n_MithrilDB_ is radically different from _libmdbx_ by the new database\nformat and API based on C++20. The goal of this revolution is to provide\na clearer and robust API, add more features and new valuable properties\nof the database. All fundamental architectural problems of libmdbx/LMDB\nhave been solved there, but now the active development has been\nsuspended for top-three reasons:\n\n1. For now _libmdbx_ mostly enough and I’m busy for scalability.\n2. Waiting for fresh [Elbrus CPU](https://wiki.elbrus.ru/) of [e2k architecture](https://en.wikipedia.org/wiki/Elbrus_2000),\nespecially with hardware acceleration of [Streebog](https://en.wikipedia.org/wiki/Streebog) and\n[Kuznyechik](https://en.wikipedia.org/wiki/Kuznyechik), which are required for Merkle tree, etc.\n3. The expectation of needs and opportunities due to the wide use of NVDIMM (aka persistent memory),\nmodern NVMe and [Ангара](https://ru.wikipedia.org/wiki/Ангара_(интерконнект)).\n\nHowever, _MithrilDB_ will not be available for countries unfriendly to\nRussia (i.e. acceded the sanctions, devil adepts and/or NATO). But it is\nnot yet known whether such restriction will be implemented only through\na license and support, either the source code will not be open at all.\nBasically I am not inclined to allow my work to contribute to the\nprofit that goes to weapons that kill my relatives and friends.\nNO OPTIONS.\n\nNonetheless, I try not to make any promises regarding _MithrilDB_ until release.\n\nContrary to _MithrilDB_, _libmdbx_ will forever free and open source.\nMoreover with high-quality support whenever possible. Tu deviens\nresponsable pour toujours de ce que tu as apprivois. So I will continue\nto comply with the original open license and the principles of\nconstructive cooperation, in spite of outright Github sabotage and\nsanctions. I will also try to keep (not drop) Windows support, despite\nit is an unused obsolete technology for us.\n\n\u003c!-- section-end --\u003e\n\n```\n$ objdump -f -h -j .text libmdbx.so\n\n  libmdbx.so:     формат файла elf64-e2k\n  архитектура: elbrus-v6:64, флаги 0x00000150:\n  HAS_SYMS, DYNAMIC, D_PAGED\n  начальный адрес 0x00000000??????00\n\n  Разделы:\n  Idx Name          Разм      VMA               LMA               Фа  смещ.  Выр.  Флаги\n   10 .text         000e7460  0000000000025c00  0000000000025c00  00025c00  2**10  CONTENTS, ALLOC, LOAD, READONLY, CODE\n\n$ cc --version\n  lcc:1.27.14:Jan-31-2024:e2k-v6-linux\n  gcc (GCC) 9.3.0 compatible\n```\n\n-----\n\n## Table of Contents\n- [Characteristics](#characteristics)\n    - [Features](#features)\n    - [Limitations](#limitations)\n    - [Gotchas](#gotchas)\n    - [Comparison with other databases](#comparison-with-other-databases)\n    - [Improvements beyond LMDB](#improvements-beyond-lmdb)\n    - [History \u0026 Acknowledgments](#history)\n- [Usage](#usage)\n    - [Building and Testing](#building-and-testing)\n    - [API description](#api-description)\n    - [Bindings](#bindings)\n- [Performance comparison](#performance-comparison)\n    - [Integral performance](#integral-performance)\n    - [Read scalability](#read-scalability)\n    - [Sync-write mode](#sync-write-mode)\n    - [Lazy-write mode](#lazy-write-mode)\n    - [Async-write mode](#async-write-mode)\n    - [Cost comparison](#cost-comparison)\n\n# Characteristics\n\n\u003c!-- section-begin characteristics --\u003e\n\n## Features\n\n- Key-value data model, keys are always sorted.\n\n- Fully [ACID](https://en.wikipedia.org/wiki/ACID)-compliant, through to\n[MVCC](https://en.wikipedia.org/wiki/Multiversion_concurrency_control)\nand [CoW](https://en.wikipedia.org/wiki/Copy-on-write).\n\n- Multiple key-value tables/sub-databases within a single datafile.\n\n- Range lookups, including range query estimation.\n\n- Efficient support for short fixed length keys, including native 32/64-bit integers.\n\n- Ultra-efficient support for [multimaps](https://en.wikipedia.org/wiki/Multimap). Multi-values sorted, searchable and iterable. Keys stored without duplication.\n\n- Data is [memory-mapped](https://en.wikipedia.org/wiki/Memory-mapped_file) and accessible directly/zero-copy. Traversal of database records is extremely-fast.\n\n- Transactions for readers and writers, ones do not block others.\n\n- Writes are strongly serialized. No transaction conflicts nor deadlocks.\n\n- Readers are [non-blocking](https://en.wikipedia.org/wiki/Non-blocking_algorithm), notwithstanding [snapshot isolation](https://en.wikipedia.org/wiki/Snapshot_isolation).\n\n- Nested write transactions.\n\n- Reads scale linearly across CPUs.\n\n- Continuous zero-overhead database compactification.\n\n- Automatic on-the-fly database size adjustment.\n\n- Customizable database page size.\n\n- `Olog(N)` cost of lookup, insert, update, and delete operations by virtue of [B+ tree characteristics](https://en.wikipedia.org/wiki/B%2B_tree#Characteristics).\n\n- Online hot backup.\n\n- Append operation for efficient bulk insertion of pre-sorted data.\n\n- No [WAL](https://en.wikipedia.org/wiki/Write-ahead_logging) nor any transaction journal. No crash recovery needed. No maintenance is required.\n\n- No internal cache and/or memory management, all done by basic OS services.\n\n## Limitations\n\n- **Page size**: a power of 2, minimum `256` (mostly for testing), maximum `65536` bytes, default `4096` bytes.\n- **Key size**: minimum `0`, maximum ≈½ pagesize (`2022` bytes for default 4K pagesize, `32742` bytes for 64K pagesize).\n- **Value size**: minimum `0`, maximum `2146435072` (`0x7FF00000`) bytes for maps, ≈½ pagesize for multimaps (`2022` bytes for default 4K pagesize, `32742` bytes for 64K pagesize).\n- **Write transaction size**: up to `1327217884` pages (`4.944272` TiB for default 4K pagesize, `79.108351` TiB for 64K pagesize).\n- **Database size**: up to `2147483648` pages (≈`8.0` TiB for default 4K pagesize, ≈`128.0` TiB for 64K pagesize).\n- **Maximum tables/sub-databases**: `32765`.\n\n## Gotchas\n\n1. There cannot be more than one writer at a time, i.e. no more than one write transaction at a time.\n\n2. _libmdbx_ is based on [B+ tree](https://en.wikipedia.org/wiki/B%2B_tree), so access to database pages is mostly random.\nThus SSDs provide a significant performance boost over spinning disks for large databases.\n\n3. _libmdbx_ uses [shadow paging](https://en.wikipedia.org/wiki/Shadow_paging) instead of [WAL](https://en.wikipedia.org/wiki/Write-ahead_logging).\nThus syncing data to disk might be a bottleneck for write intensive workload.\n\n4. _libmdbx_ uses [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write) for [snapshot isolation](https://en.wikipedia.org/wiki/Snapshot_isolation) during updates,\nbut read transactions prevents recycling an old retired/freed pages, since it read ones. Thus altering of data during a parallel\nlong-lived read operation will increase the process work set, may exhaust entire free database space,\nthe database can grow quickly, and result in performance degradation.\nTry to avoid long running read transactions, otherwise use [transaction parking](https://libmdbx.dqdkfa.ru/group__c__transactions.html#ga2c2c97730ff35cadcedfbd891ac9b12f)\nand/or [Handle-Slow-Readers callback](https://libmdbx.dqdkfa.ru/group__c__err.html#ga2cb11b56414c282fe06dd942ae6cade6).\n\n5. _libmdbx_ is extraordinarily fast and provides minimal overhead for data access,\nso you should reconsider using brute force techniques and double check your code.\nOn the one hand, in the case of _libmdbx_, a simple linear search may be more profitable than complex indexes.\nOn the other hand, if you make something suboptimally, you can notice detrimentally only on sufficiently large data.\n\n## Comparison with other databases\nFor now please refer to [chapter of \"BoltDB comparison with other\ndatabases\"](https://github.com/coreos/bbolt#comparison-with-other-databases)\nwhich is also (mostly) applicable to _libmdbx_ with minor clarification:\n - a database could shared by multiple processes, i.e. no multi-process issues;\n - no issues with moving a cursor(s) after the deletion;\n - _libmdbx_ provides zero-overhead database compactification, so a database file could be shrinked/truncated in particular cases;\n - excluding disk I/O time _libmdbx_ could be ≈3 times faster than BoltDB and up to 10-100K times faster than both BoltDB and LMDB in particular extreme cases;\n - _libmdbx_ provides more features compared to BoltDB and/or LMDB.\n\n\u003c!-- section-end --\u003e\n\n\u003c!-- section-begin improvements --\u003e\n\nImprovements beyond LMDB\n========================\n\n_libmdbx_ is superior to legendary _[LMDB](https://symas.com/lmdb/)_ in\nterms of features and reliability, not inferior in performance. In\ncomparison to _LMDB_, _libmdbx_ make things \"just work\" perfectly and\nout-of-the-box, not silently and catastrophically break down. The list\nbelow is pruned down to the improvements most notable and obvious from\nthe user's point of view.\n\n## Some Added Features\n\n1. Keys could be more than 2 times longer than _LMDB_.\n   \u003e For DB with default page size _libmdbx_ support keys up to 2022 bytes\n   \u003e and up to 32742 bytes for 64K page size. _LMDB_ allows key size up to\n   \u003e 511 bytes and may silently loses data with large values.\n\n2. Up to 30% faster than _LMDB_ in [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) benchmarks.\n   \u003e Benchmarks of the in-[tmpfs](https://en.wikipedia.org/wiki/Tmpfs) scenarios,\n   \u003e that tests the speed of the engine itself, showned that _libmdbx_ 10-20% faster than _LMDB_,\n   \u003e and up to 30% faster when _libmdbx_ compiled with specific build options\n   \u003e which downgrades several runtime checks to be match with LMDB behaviour.\n   \u003e\n   \u003e However, libmdbx may be slower than LMDB on Windows, since uses native file locking API.\n   \u003e These locks are really slow, but they prevent an inconsistent backup from being obtained by copying the DB file during an ongoing write transaction.\n   \u003e So I think this is the right decision, and for speed, it's better to use Linux, or ask Microsoft to fix up file locks.\n   \u003e\n   \u003e Noted above and other results could be easily reproduced with [ioArena](https://abf.io/erthink/ioarena) just by `make bench-quartet` command,\n   \u003e including comparisons with [RockDB](https://en.wikipedia.org/wiki/RocksDB)\n   \u003e and [WiredTiger](https://en.wikipedia.org/wiki/WiredTiger).\n\n3. Automatic on-the-fly database size adjustment, both increment and reduction.\n   \u003e _libmdbx_ manages the database size according to parameters specified\n   \u003e by `mdbx_env_set_geometry()` function,\n   \u003e ones include the growth step and the truncation threshold.\n   \u003e\n   \u003e Unfortunately, on-the-fly database size adjustment doesn't work under [Wine](https://en.wikipedia.org/wiki/Wine_(software))\n   \u003e due to its internal limitations and unimplemented functions, i.e. the `MDBX_UNABLE_EXTEND_MAPSIZE` error will be returned.\n\n4. Automatic continuous zero-overhead database compactification.\n   \u003e During each commit _libmdbx_ merges a freeing pages which adjacent with the unallocated area\n   \u003e at the end of file, and then truncates unused space when a lot enough of.\n\n5. The same database format for 32- and 64-bit builds.\n   \u003e _libmdbx_ database format depends only on the [endianness](https://en.wikipedia.org/wiki/Endianness) but not on the [bitness](https://en.wiktionary.org/wiki/bitness).\n\n6. The \"Big Foot\" feature than solves speific performance issues with huge transactions and extra-large page-number-lists.\n\n7. LIFO policy for Garbage Collection recycling. This can significantly increase write performance due write-back disk cache up to several times in a best case scenario.\n   \u003e LIFO means that for reuse will be taken the latest becomes unused pages.\n   \u003e Therefore the loop of database pages circulation becomes as short as possible.\n   \u003e In other words, the set of pages, that are (over)written in memory and on disk during a series of write transactions, will be as small as possible.\n   \u003e Thus creates ideal conditions for the battery-backed or flash-backed disk cache efficiency.\n\n8. Parking of read transactions with ousting and auto-restart, [Handle-Slow-Readers callback](https://libmdbx.dqdkfa.ru/group__c__err.html#ga2cb11b56414c282fe06dd942ae6cade6) to resolve an issues due to long-lived read transactions.\n\n9. Fast estimation of range query result volume, i.e. how many items can\nbe found between a `KEY1` and a `KEY2`. This is a prerequisite for build\nand/or optimize query execution plans.\n   \u003e _libmdbx_ performs a rough estimate based on common B-tree pages of the paths from root to corresponding keys.\n\n10. Database integrity check API both with standalone `mdbx_chk` utility.\n\n11. Support for opening databases in the exclusive mode, including on a network share.\n\n12. Extended information of whole-database, tables/sub-databases, transactions, readers enumeration.\n   \u003e _libmdbx_ provides a lot of information, including dirty and leftover pages\n   \u003e for a write transaction, reading lag and holdover space for read transactions.\n\n13. Support of Zero-length for keys and values.\n\n14. Useful runtime options for tuning engine to application's requirements and use cases specific.\n\n15. Automated steady sync-to-disk upon several thresholds and/or timeout via cheap polling.\n\n16. Ability to determine whether the particular data is on a dirty page\nor not, that allows to avoid copy-out before updates.\n\n17. Extended update and delete operations.\n   \u003e _libmdbx_ allows one _at once_ with getting previous value\n   \u003e and addressing the particular item from multi-value with the same key.\n\n18. Sequence generation and three persistent 64-bit vector-clock like markers.\n\n## Other fixes and specifics\n\n1. Fixed more than 10 significant errors, in particular: page leaks,\nwrong table/sub-database statistics, segfault in several conditions,\nnonoptimal page merge strategy, updating an existing record with\na change in data size (including for multimap), etc.\n\n2. All cursors can be reused and should be closed explicitly,\nregardless ones were opened within a write or read transaction.\n\n3. Opening database handles are spared from race conditions and\npre-opening is not needed.\n\n4. Returning `MDBX_EMULTIVAL` error in case of ambiguous update or delete.\n\n5. Guarantee of database integrity even in asynchronous unordered write-to-disk mode.\n   \u003e _libmdbx_ propose additional trade-off by `MDBX_SAFE_NOSYNC` with append-like manner for updates,\n   \u003e that avoids database corruption after a system crash contrary to LMDB.\n   \u003e Nevertheless, the `MDBX_UTTERLY_NOSYNC` mode is available to match LMDB's behaviour for `MDB_NOSYNC`.\n\n6. On **MacOS \u0026 iOS** the `fcntl(F_FULLFSYNC)` syscall is used _by\ndefault_ to synchronize data with the disk, as this is [the only way to\nguarantee data\ndurability](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fsync.2.html)\nin case of power failure. Unfortunately, in scenarios with high write\nintensity, the use of `F_FULLFSYNC` significantly degrades performance\ncompared to LMDB, where the `fsync()` syscall is used. Therefore,\n_libmdbx_ allows you to override this behavior by defining the\n`MDBX_OSX_SPEED_INSTEADOF_DURABILITY=1` option while build the library.\n\n7. On **Windows** the `LockFileEx()` syscall is used for locking, since\nit allows place the database on network drives, and provides protection\nagainst incompetent user actions (aka\n[poka-yoke](https://en.wikipedia.org/wiki/Poka-yoke)). Therefore\n_libmdbx_ may be a little lag in performance tests from LMDB where the\nnamed mutexes are used.\n\n\u003c!-- section-end --\u003e\n\u003c!-- section-begin history --\u003e\n\n# History\n\nHistorically, _libmdbx_ is a deeply revised and extended descendant of the\n[Lightning Memory-Mapped Database](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database).\nAt first the development was carried out within the\n[ReOpenLDAP](https://web.archive.org/web/https://github.com/erthink/ReOpenLDAP) project. About a\nyear later _libmdbx_ was separated into a standalone project, which was\n[presented at Highload++ 2015\nconference](http://www.highload.ru/2015/abstracts/1831.html).\n\nSince 2017 _libmdbx_ is used in [Fast Positive Tables](https://gitflic.ru/project/erthink/libfpta),\nand until 2025 development was funded by [Positive Technologies](https://www.ptsecurity.com).\nSince 2020 _libmdbx_ is used in Ethereum: [Erigon](https://github.com/erigontech/erigon), [Akula](https://github.com/akula-bft/akula),\n[Silkworm](https://github.com/erigontech/silkworm), [Reth](https://github.com/paradigmxyz/reth), etc.\n\nOn 2022-04-15 the Github administration, without any warning nor\nexplanation, deleted _libmdbx_ along with a lot of other projects,\nsimultaneously blocking access for many developers. Therefore on\n2022-04-21 I have migrated to a reliable trusted infrastructure.\nThe origin for now is at [GitFlic](https://gitflic.ru/project/erthink/libmdbx)\nwith backup at [ABF by ROSA Лаб](https://abf.rosalinux.ru/erthink/libmdbx).\nFor the same reason ~~Github~~ is blacklisted forever.\n\nSince May 2024 and version 0.13 _libmdbx_ was re-licensed under Apache-2.0 license.\nPlease refer to the [`COPYRIGHT` file](https://gitflic.ru/project/erthink/libmdbx/blob/raw?file=COPYRIGHT) for license change explanations.\n\n\n## Acknowledgments\nHoward Chu \u003chyc@openldap.org\u003e and Hallvard Furuseth\n\u003challvard@openldap.org\u003e are the authors of _LMDB_, from which _libmdbx_\nwas forked in 2015.\n\nMartin Hedenfalk \u003cmartin@bzero.se\u003e is the author of `btree.c` code, which\nwas used to begin development of _LMDB_.\n\n\u003c!-- section-end --\u003e\n\n--------------------------------------------------------------------------------\n\nUsage\n=====\n\n\u003c!-- section-begin usage --\u003e\n\nCurrently, libmdbx is only available in a\n[source code](https://en.wikipedia.org/wiki/Source_code) form.\nPackages support for common Linux distributions is planned in the future,\nsince release the version 1.0.\n\nThe source code is availale on\n[Gitflic](https://gitflic.ru/project/erthink/libmdbx) and mirrors on [abf.io](https://abf.io/erthink/libmdbx),\n[hub.mos.ru](https://hub.mos.ru/leo/libmdbx) and [Github](https://github.com/erthink/libmdbx).\nPlease use the `stable` branch or the latest release for production environment through stagging\nand the `master` branch for development a derivative projects.\n\n## Source code embedding\n\n_libmdbx_ provides three official ways for integration in source code form:\n\n1. Using an amalgamated source code which available in the [releases section](https://gitflic.ru/project/erthink/libmdbx/release) on GitFlic.\n   \u003e An amalgamated source code includes all files required to build and\n   \u003e use _libmdbx_, but not for testing _libmdbx_ itself.\n   \u003e Beside the releases an amalgamated sources could be created any time from the original clone of git\n   \u003e repository on Linux by executing `make dist`. As a result, the desired\n   \u003e set of files will be formed in the `dist` subdirectory.\n\n2. Using [Conan Package Manager](https://conan.io/):\n    - optional: Setup your own conan-server;\n    - Create conan-package by `conan create .` inside the _libmdbx_' repo subdirectory;\n    - optional: Upload created recipe and/or package to the conan-server by `conan upload -r SERVER 'mdbx/*'`;\n    - Consume libmdbx-package from the local conan-cache or from conan-server in accordance with the [Conan tutorial](https://docs.conan.io/2/tutorial/consuming_packages.html).\n\n3. Adding the complete source code as a `git submodule` from the [origin git repository](https://gitflic.ru/project/erthink/libmdbx) on GitFlic.\n   \u003e This allows you to build as _libmdbx_ and testing tool.\n   \u003e  On the other hand, this way requires you to pull git tags, and use C++11 compiler for test tool.\n\n_**Please, avoid using any other techniques.**_ Otherwise, at least\ndon't ask for support and don't name such chimeras `libmdbx`.\n\n\n\n## Building and Testing\n\nBoth amalgamated and original source code provides build through the use\n[CMake](https://cmake.org/) or [GNU\nMake](https://www.gnu.org/software/make/) with\n[bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)).\n\nAll build ways\nare completely traditional and have minimal prerequirements like\n`build-essential`, i.e. the non-obsolete C/C++ compiler and a\n[SDK](https://en.wikipedia.org/wiki/Software_development_kit) for the\ntarget platform.\nObviously you need building tools itself, i.e. `git`,\n`cmake` or GNU `make` with `bash`. For your convenience, `make help`\nand `make options` are also available for listing existing targets\nand build options respectively.\n\nThe only significant specificity is that git' tags are required\nto build from complete (not amalgamated) source codes.\nExecuting **`git fetch --tags --force --prune`** is enough to get ones,\nand `--unshallow` or `--update-shallow` is required for shallow cloned case.\n\nSo just using CMake or GNU Make in your habitual manner and feel free to\nfill an issue or make pull request in the case something will be\nunexpected or broken down.\n\n### Testing\nThe amalgamated source code does not contain any tests for or several reasons.\nPlease read [the explanation](https://libmdbx.dqdkfa.ru/dead-github/issues/214#issuecomment-870717981) and don't ask to alter this.\nSo for testing _libmdbx_ itself you need a full source code, i.e. the clone of a git repository, there is no option.\n\nThe full source code of _libmdbx_ has a [`test` subdirectory](https://gitflic.ru/project/erthink/libmdbx/tree/master/test) with minimalistic test \"framework\".\nActually yonder is a source code of the `mdbx_test` – console utility which has a set of command-line options that allow construct and run a reasonable enough test scenarios.\nThis test utility is intended for _libmdbx_'s developers for testing library itself, but not for use by users.\nTherefore, only basic information is provided:\n\n   - There are few CRUD-based test cases (hill, TTL, nested, append, jitter, etc),\n     which can be combined to test the concurrent operations within shared database in a multi-processes environment.\n     This is the `basic` test scenario.\n   - The `Makefile` provide several self-described targets for testing: `smoke`, `test`, `check`, `memcheck`, `test-valgrind`,\n     `test-asan`, `test-leak`, `test-ubsan`, `cross-gcc`, `cross-qemu`, `gcc-analyzer`, `smoke-fault`, `smoke-singleprocess`,\n     `test-singleprocess`, `long-test`. Please run `make --help` if doubt.\n   - In addition to the `mdbx_test` utility, there is the script [`stochastic.sh`](https://gitflic.ru/project/erthink/libmdbx/blob/master/test/stochastic.sh),\n     which calls `mdbx_test` by going through set of modes and options, with gradually increasing the number of operations and the size of transactions.\n     This script is used for mostly of all automatic testing, including `Makefile` targets and Continuous Integration.\n   - Brief information of available command-line options is available by `--help`.\n     However, you should dive into source code to get all, there is no option.\n\nAnyway, no matter how thoroughly the _libmdbx_ is tested, you should rely only on your own tests for a few reasons:\n\n1. Mostly of all use cases are unique.\n   So it is no warranty that your use case was properly tested, even the _libmdbx_'s tests engages stochastic approach.\n2. If there are problems, then your test on the one hand will help to verify whether you are using _libmdbx_ correctly,\n   on the other hand it will allow to reproduce the problem and insure against regression in a future.\n3. Actually you should rely on than you checked by yourself or take a risk.\n\n\n### Common important details\n\n#### Build reproducibility\nBy default _libmdbx_ track build time via `MDBX_BUILD_TIMESTAMP` build option and macro.\nSo for a [reproducible builds](https://en.wikipedia.org/wiki/Reproducible_builds) you should predefine/override it to known fixed string value.\nFor instance:\n\n - for reproducible build with make: `make MDBX_BUILD_TIMESTAMP=unknown ` ...\n - or during configure by CMake: `cmake -DMDBX_BUILD_TIMESTAMP:STRING=unknown ` ...\n\nOf course, in addition to this, your toolchain must ensure the reproducibility of builds.\nFor more information please refer to [reproducible-builds.org](https://reproducible-builds.org/).\n\n#### Containers\nThere are no special traits nor quirks if you use _libmdbx_ ONLY inside\nthe single container. But in a cross-container(s) or with a host-container(s)\ninteroperability cases the three major things MUST be guaranteed:\n\n1. Coherence of memory mapping content and unified page cache inside OS\nkernel for host and all container(s) operated with a DB. Basically this\nmeans must be only a single physical copy of each memory mapped DB' page\nin the system memory.\n\n2. Uniqueness of [PID](https://en.wikipedia.org/wiki/Process_identifier) values and/or a common space for ones:\n    - for POSIX systems: PID uniqueness for all processes operated with a DB.\n      I.e. the `--pid=host` is required for run DB-aware processes inside Docker,\n      either without host interaction a `--pid=container:\u003cname|id\u003e` with the same name/id.\n    - for non-POSIX (i.e. Windows) systems: inter-visibility of processes handles.\n      I.e. the `OpenProcess(SYNCHRONIZE, ..., PID)` must return reasonable error,\n      including `ERROR_ACCESS_DENIED`,\n      but not the `ERROR_INVALID_PARAMETER` as for an invalid/non-existent PID.\n\n3. The versions/builds of _libmdbx_ and `libc`/`pthreads` (`glibc`, `musl`, etc) must be be compatible.\n   - Basically, the `options:` string in the output of `mdbx_chk -V` must be the same for host and container(s).\n     See `MDBX_LOCKING`, `MDBX_USE_OFDLOCKS` and other build options for details.\n   - Avoid using different versions of `libc`, especially mixing different implementations, i.e. `glibc` with `musl`, etc.\n     Prefer to use the same LTS version, or switch to full virtualization/isolation if in doubt.\n\n#### DSO/DLL unloading and destructors of Thread-Local-Storage objects\nWhen building _libmdbx_ as a shared library or use static _libmdbx_ as a\npart of another dynamic library, it is advisable to make sure that your\nsystem ensures the correctness of the call destructors of\nThread-Local-Storage objects when unloading dynamic libraries.\n\nIf this is not the case, then unloading a dynamic-link library with\n_libmdbx_ code inside, can result in either a resource leak or a crash\ndue to calling destructors from an already unloaded DSO/DLL object. The\nproblem can only manifest in a multithreaded application, which makes\nthe unloading of shared dynamic libraries with _libmdbx_ code inside,\nafter using _libmdbx_. It is known that TLS-destructors are properly\nmaintained in the following cases:\n\n- On all modern versions of Windows (Windows 7 and later).\n\n- On systems with the\n[`__cxa_thread_atexit_impl()`](https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables)\nfunction in the standard C library, including systems with GNU libc\nversion 2.18 and later.\n\n- On systems with libpthread/ntpl from GNU libc with bug fixes\n[#21031](https://sourceware.org/bugzilla/show_bug.cgi?id=21031) and\n[#21032](https://sourceware.org/bugzilla/show_bug.cgi?id=21032), or\nwhere there are no similar bugs in the pthreads implementation.\n\n### Linux and other platforms with GNU Make\nTo build the library it is enough to execute `make all` in the directory\nof source code, and `make check` to execute the basic tests.\n\nIf the `make` installed on the system is not GNU Make, there will be a\nlot of errors from make when trying to build. In this case, perhaps you\nshould use `gmake` instead of `make`, or even `gnu-make`, etc.\n\n### FreeBSD and related platforms\nAs a rule on BSD and it derivatives the default is to use Berkeley Make and\n[Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)) is not installed.\n\nSo you need to install the required components: GNU Make, Bash, C and C++\ncompilers compatible with GCC or CLANG. After that, to build the\nlibrary, it is enough to execute `gmake all` (or `make all`) in the\ndirectory with source code, and `gmake check` (or `make check`) to run\nthe basic tests.\n\n### Windows\nFor build _libmdbx_ on Windows the _original_ CMake and [Microsoft Visual\nStudio 2019](https://en.wikipedia.org/wiki/Microsoft_Visual_Studio) are\nrecommended. Please use the recent versions of CMake, Visual Studio and Windows\nSDK to avoid troubles with C11 support and `alignas()` feature.\n\nFor build by MinGW the 10.2 or recent version coupled with a modern CMake are required.\nSo it is recommended to use [chocolatey](https://chocolatey.org/) to install and/or update the ones.\n\nAnother ways to build is potentially possible but not supported and will not.\nThe `CMakeLists.txt` or `GNUMakefile` scripts will probably need to be modified accordingly.\nUsing other methods do not forget to add the `ntdll.lib` to linking.\n\nIt should be noted that in _libmdbx_ was efforts to avoid\nruntime dependencies from CRT and other MSVC libraries.\nFor this is enough to pass the `-DMDBX_WITHOUT_MSVC_CRT:BOOL=ON` option\nduring configure by CMake.\n\nTo run the [long stochastic test scenario](test/stochastic.sh),\n[bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)) is required, and\nsuch testing is recommended with placing the test data on the\n[RAM-disk](https://en.wikipedia.org/wiki/RAM_drive).\n\n### Windows Subsystem for Linux\n_libmdbx_ could be used in [WSL2](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_2)\nbut NOT in [WSL1](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_1) environment.\nThis is a consequence of the fundamental shortcomings of _WSL1_ and cannot be fixed.\nTo avoid data loss, _libmdbx_ returns the `ENOLCK` (37, \"No record locks available\")\nerror when opening the database in a _WSL1_ environment.\n\n### MacOS\nCurrent [native build tools](https://en.wikipedia.org/wiki/Xcode) for\nMacOS include GNU Make, CLANG and an outdated version of Bash.\nHowever, the build script uses GNU-kind of `sed` and `tar`.\nSo the easiest way to install all prerequirements is to use [Homebrew](https://brew.sh/),\njust by `brew install bash make cmake ninja gnu-sed gnu-tar --with-default-names`.\n\nNext, to build the library, it is enough to run `make all` in the\ndirectory with source code, and run `make check` to execute the base\ntests. If something goes wrong, it is recommended to install\n[Homebrew](https://brew.sh/) and try again.\n\nTo run the [long stochastic test scenario](test/stochastic.sh), you\nwill need to install the current (not outdated) version of\n[Bash](https://en.wikipedia.org/wiki/Bash_(Unix_shell)).\nJust install it as noted above.\n\n### Android\nI recommend using CMake to build _libmdbx_ for Android.\nPlease refer to the [official guide](https://developer.android.com/studio/projects/add-native-code).\n\n### iOS\nTo build _libmdbx_ for iOS, I recommend using CMake with the\n[\"toolchain file\"](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html)\nfrom the [ios-cmake](https://github.com/leetal/ios-cmake) project.\n\n\u003c!-- section-end --\u003e\n\n## API description\n\nPlease refer to the online [_libmdbx_ API reference](https://libmdbx.dqdkfa.ru/docs)\nand/or see the [mdbx.h++](mdbx.h%2B%2B) and [mdbx.h](mdbx.h) headers.\n\n\u003c!-- section-begin bindings --\u003e\n\nBindings\n========\n\n| Runtime |  Repo  | Author |\n| ------- | ------ | ------ |\n| Rust    | [libmdbx-rs](https://github.com/vorot93/libmdbx-rs)   | [Artem Vorotnikov](https://github.com/vorot93) |\n| Python  | [PyPi/libmdbx](https://pypi.org/project/libmdbx/)     | [Lazymio](https://github.com/wtdcode) |\n| Java    | [mdbxjni](https://github.com/castortech/mdbxjni)      | [Castor Technologies](https://castortech.com/) |\n| Go      | [mdbx-go](https://github.com/torquem-ch/mdbx-go)      | [Alex Sharov](https://github.com/AskAlexSharov) |\n| Ruby    | [ruby-mdbx](https://rubygems.org/gems/mdbx/)          | [Mahlon E. Smith](https://github.com/mahlonsmith) |\n| Zig     | [mdbx-zig](https://github.com/theseyan/lmdbx-zig)     | [Sayan J. Das](https://github.com/theseyan) |\n\n##### Obsolete/Outdated/Unsupported:\n\n| Runtime |  Repo  | Author |\n| ------- | ------ | ------ |\n| .NET    | [mdbx.NET](https://github.com/wangjia184/mdbx.NET) | [Jerry Wang](https://github.com/wangjia184) |\n| Scala   | [mdbx4s](https://github.com/david-bouyssie/mdbx4s) | [David Bouyssié](https://github.com/david-bouyssie) |\n| Rust    | [mdbx](https://crates.io/crates/mdbx)                 | [gcxfd](https://github.com/gcxfd) |\n| Haskell | [libmdbx-hs](https://hackage.haskell.org/package/libmdbx) | [Francisco Vallarino](https://github.com/fjvallarino) |\n| Lua     | [lua-libmdbx](https://github.com/mah0x211/lua-libmdbx) | [Masatoshi Fukunaga](https://github.com/mah0x211) |\n| NodeJS, [Deno](https://deno.land/) | [lmdbx-js](https://github.com/kriszyp/lmdbx-js) | [Kris Zyp](https://github.com/kriszyp/)\n| NodeJS  | [node-mdbx](https://www.npmjs.com/package/node-mdbx/) | [Сергей Федотов](mailto:sergey.fedotov@corp.mail.ru) |\n| Nim     | [NimDBX](https://github.com/snej/nimdbx) | [Jens Alfke](https://github.com/snej)\n\n\u003c!-- section-end --\u003e\n\n--------------------------------------------------------------------------------\n\n\u003c!-- section-begin performance --\u003e\n\nPerformance comparison\n======================\n\nOver the past 10 years, _libmdbx_ has had a lot of significant\nimprovements and innovations. _libmdbx_ has become a slightly faster in\nsimple cases and many times faster in complex scenarios, especially with\na huge transactions in gigantic databases. Therefore, on the one hand,\nthe results below are outdated. However, on the other hand, these simple\nbenchmarks are evident, easy to reproduce, and are close to the most\ncommon use cases.\n\nThe following all benchmark results were obtained in 2015 by [IOArena](https://abf.io/erthink/ioarena)\nand multiple [scripts](https://github.com/pmwkaa/ioarena/tree/HL%2B%2B2015)\nruns on my laptop (i7-4600U 2.1 GHz, SSD MZNTD512HAGL-000L1).\n\n## Integral performance\n\nHere showed sum of performance metrics in 3 benchmarks:\n\n - Read/Search on the machine with 4 logical CPUs in HyperThreading mode (i.e. actually 2 physical CPU cores);\n\n - Transactions with [CRUD](https://en.wikipedia.org/wiki/CRUD)\n operations in sync-write mode (fdatasync is called after each\n transaction);\n\n - Transactions with [CRUD](https://en.wikipedia.org/wiki/CRUD)\n operations in lazy-write mode (moment to sync data to persistent storage\n is decided by OS).\n\n*Reasons why asynchronous mode isn't benchmarked here:*\n\n  1. It doesn't make sense as it has to be done with DB engines, oriented\n  for keeping data in memory e.g. [Tarantool](https://tarantool.io/),\n  [Redis](https://redis.io/)), etc.\n\n  2. Performance gap is too high to compare in any meaningful way.\n\n![Comparison #1: Integral Performance](https://libmdbx.dqdkfa.ru/img/perf-slide-1.png)\n\n--------------------------------------------------------------------------------\n\n## Read Scalability\n\nSummary performance with concurrent read/search queries in 1-2-4-8\nthreads on the machine with 4 logical CPUs in HyperThreading mode (i.e.\nactually 2 physical CPU cores).\n\n![Comparison #2: Read Scalability](https://libmdbx.dqdkfa.ru/img/perf-slide-2.png)\n\n--------------------------------------------------------------------------------\n\n## Sync-write mode\n\n - Linear scale on left and dark rectangles mean arithmetic mean\n transactions per second;\n\n - Logarithmic scale on right is in seconds and yellow intervals mean\n execution time of transactions. Each interval shows minimal and maximum\n execution time, cross marks standard deviation.\n\n**10,000 transactions in sync-write mode**. In case of a crash all data\nis consistent and conforms to the last successful transaction. The\n[fdatasync](https://linux.die.net/man/2/fdatasync) syscall is used after\neach write transaction in this mode.\n\nIn the benchmark each transaction contains combined CRUD operations (2\ninserts, 1 read, 1 update, 1 delete). Benchmark starts on an empty database\nand after full run the database contains 10,000 small key-value records.\n\n![Comparison #3: Sync-write mode](https://libmdbx.dqdkfa.ru/img/perf-slide-3.png)\n\n--------------------------------------------------------------------------------\n\n## Lazy-write mode\n\n - Linear scale on left and dark rectangles mean arithmetic mean of\n thousands transactions per second;\n\n - Logarithmic scale on right in seconds and yellow intervals mean\n execution time of transactions. Each interval shows minimal and maximum\n execution time, cross marks standard deviation.\n\n**100,000 transactions in lazy-write mode**. In case of a crash all data\nis consistent and conforms to the one of last successful transactions, but\ntransactions after it will be lost. Other DB engines use\n[WAL](https://en.wikipedia.org/wiki/Write-ahead_logging) or transaction\njournal for that, which in turn depends on order of operations in the\njournaled filesystem. _libmdbx_ doesn't use WAL and hands I/O operations\nto filesystem and OS kernel (mmap).\n\nIn the benchmark each transaction contains combined CRUD operations (2\ninserts, 1 read, 1 update, 1 delete). Benchmark starts on an empty database\nand after full run the database contains 100,000 small key-value\nrecords.\n\n\n![Comparison #4: Lazy-write mode](https://libmdbx.dqdkfa.ru/img/perf-slide-4.png)\n\n--------------------------------------------------------------------------------\n\n## Async-write mode\n\n - Linear scale on left and dark rectangles mean arithmetic mean of\n thousands transactions per second;\n\n - Logarithmic scale on right in seconds and yellow intervals mean\n execution time of transactions. Each interval shows minimal and maximum\n execution time, cross marks standard deviation.\n\n**1,000,000 transactions in async-write mode**.\nIn case of a crash all data is consistent and conforms to the one of\nlast successful transactions, but lost transaction count is much higher\nthan in lazy-write mode. All DB engines in this mode do as little writes\nas possible on persistent storage. _libmdbx_ uses\n[msync(MS_ASYNC)](https://linux.die.net/man/2/msync) in this mode.\n\nIn the benchmark each transaction contains combined CRUD operations (2\ninserts, 1 read, 1 update, 1 delete). Benchmark starts on an empty database\nand after full run the database contains 10,000 small key-value records.\n\n![Comparison #5: Async-write mode](https://libmdbx.dqdkfa.ru/img/perf-slide-5.png)\n\n--------------------------------------------------------------------------------\n\n## Cost comparison\n\nSummary of used resources during lazy-write mode benchmarks:\n\n - Read and write IOPs;\n\n - Sum of user CPU time and sys CPU time;\n\n - Used space on persistent storage after the test and closed DB, but not\n waiting for the end of all internal housekeeping operations (LSM\n compactification, etc).\n\n_ForestDB_ is excluded because benchmark showed it's resource\nconsumption for each resource (CPU, IOPs) much higher than other engines\nwhich prevents to meaningfully compare it with them.\n\nAll benchmark data is gathered by\n[getrusage()](http://man7.org/linux/man-pages/man2/getrusage.2.html)\nsyscall and by scanning the data directory.\n\n![Comparison #6: Cost comparison](https://libmdbx.dqdkfa.ru/img/perf-slide-6.png)\n\n\u003c!-- section-end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisar%2Flibmdbx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisar%2Flibmdbx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisar%2Flibmdbx/lists"}