# TidesDB: an embeddable LSM-tree storage engine written in C

> TidesDB is a transactional key-value storage engine library in C built on a log-structured merge tree, offering ACID with MVCC, five isolation levels including 2PC-XA, column families, range deletes, TTL and a configurable durability setting. It is a library rather than a database server, and it is licensed MPL-2.0.

**tidesdb/tidesdb** — High-performance write & space optimized transactional storage engine.

- Repository: https://github.com/tidesdb/tidesdb
- Website: https://tidesdb.com
- Stars: 603 · Forks: 59
- Language: C
- License: MPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/tidesdb-tidesdb

## A storage engine, deliberately not a database

TidesDB is described as a fast and efficient transactional key value storage engine library written in C, and the underlying data structure is a log-structured merge-tree, the LSM-tree. The second sentence of that description is the one that sets expectations correctly, and it is easy to skim past. It is not a full-featured database, but rather a library that can be used to build a database atop of it or used as a standalone key-value and column store. So there is no server to run, no wire protocol, no SQL layer and no user accounts. You link the library into your process, open a database against a directory, and you are responsible for the schema, the query layer and the operational surface. That is the classic embedded engine trade, and it cuts both ways. In exchange you get the storage engine's behaviour under your own process with no network hop and no client protocol to negotiate, and you give up everything a database server provides for free. The project homepage is at tidesdb.com, and the primary language is C with the repository including a vcpkg.json for package distribution.

## ACID with MVCC and five isolation levels

The first item on the feature list is ACID with MVCC, and the fifth is an extensive transactional API with 5 isolation levels, including 2PC-XA. That combination is the reason to look at this engine at all, because most embeddable key-value stores give you atomicity and durability or they give you rich transactions, and few give you both with a real multi-version concurrency control implementation underneath. MVCC is what makes the isolation levels cheap in an LSM tree, since readers can see a consistent snapshot without blocking writers or being blocked by them, and the presence of 2PC-XA means the engine can take part in a distributed transaction with a prepare and commit phase, which is the piece that distinguishes a serious transactional engine from a simple one. The API is described as extensive, and the README does not enumerate the five levels, so you would need the documentation or the header files to see the exact set. The other transactional feature worth noting is range deletes, which in an LSM-based store is not a trivial operation, since a delete has to be carried through the levels as a tombstone and eventually compacted away rather than removing bytes from a sorted run.

## Column families, key-value separation and a hybrid LSM and BTree

Three of the structural features deserve separate treatment because they change how you model data. Column families give you a way to group keys, and in an LSM engine that grouping affects compaction and layout rather than being a logical label. Key-value separation is the more interesting one, because it is the technique for keeping large values out of the sorted index so that the hot index stays small and cacheable, with the values stored separately and referenced from the index entries. Hybrid LSM and BTree combines the two structures in one engine, and the LSM side handles the write path and the BTree side is there for the point lookups and range access that a pure LSM handles less well, since every lookup in a pure LSM may have to consult several levels. The list also names ordered bidirectional iteration with range-bounded scans, which tells you that the engine supports both forward and reverse ordered traversal over a key range, and that is a capability you need for a sequential scan that does not read the whole dataset. Partitioned bloom filters sit alongside these, which is the standard way to avoid touching disk for keys that are not present, and in an LSM engine that avoidance is what makes point lookups fast enough to be useful.

## Durability is a setting, and TTL is a first-class feature

Configurable durability is listed as none, interval, or full sync, and that single line tells you more about the intended workloads than anything else in the feature list. Full sync gives you the strongest guarantee and the highest cost, interval batches the syncs, and none removes them. A storage engine that lets you turn durability off is a library aimed at workloads where you are batching, or where a lost tail of writes is acceptable because the data is recoverable elsewhere, and that is a real design choice rather than a compromise. The consequence is on you, since the setting is per database and a wrong choice there loses data silently, so the documentation of that option is worth reading closely rather than guessing from the name. TTL sits next to it as a first-class feature, which is what you want for session data, caches and event streams where entries have an inherent expiry. The remaining operational features are extensive statistics and metrics, crash safe and durable operation, and low space and write amplification. Write amplification deserves attention for an LSM tree, because the number of times a byte is rewritten during compaction is the main cost model of that design, and the claim of low amplification is the one to test with your own workload.

## Compression, portability and the build

The compression pipeline is configurable and supports Snappy, LZ4 and Zstd, so you choose between speed and ratio per your own hardware. Those three names also explain the licence section, which is worth reading because it is a multiple licence arrangement rather than a single one.

```
Mozilla Public License Version 2.0 (TidesDB)

== AND ==
BSD 2 (xxHash - Yann Collet)

== (optionally) ==
BSD 3 Clause (Snappy)
BSD 2 (LZ4)
BSD (Zstandard)
```

So the engine itself is under the Mozilla Public License 2.0, the hash function it depends on is BSD 2, and each compression codec carries its own licence, with the optional ones applying only if you enable that codec. That is a tidy arrangement for a library you might embed in a commercial product, since MPL 2.0 is file-level copyleft and lets you use the library in a larger work without imposing its licence on the whole. Portability is the other headline. The project lists Linux, macOS, Windows, BSD variants and Solaris and Illumos on x86, ARM, RISC-V and PowerPC, in both 32-bit and 64-bit forms, and the feature list says file portability, which means a database directory can be moved between platforms. The build is CMake based, with a CMakeLists.txt at the top level and a cmake/ directory, and the repository also carries external/ for vendored dependencies, a bench/ directory for benchmarks, a fuzz/ directory, a test/ directory, and clang-format configuration with both a shell and a PowerShell formatter script.

## Where an embeddable engine is the wrong choice

There are clear cases where a storage engine library is the wrong level of abstraction. If your team wants a database with a wire protocol, a client library in several languages, replication, backups that you do not write yourself and a query language, an embedded engine in C is the wrong tool, and the operational burden of running a database server is exactly what you were trying to avoid. If you need secondary indexes, or joins, or transactions spanning rows in a way the API does not express, the same applies. There is also the question of maturity and the size of the community around a project at this version. The release numbering is at v10.2.1, with v10.2.0 and v10.1.1 in the same week, which shows active work, but the version number also signals that the API has had ten rounds of change and the headers are the specification. A team embedding this in a long-lived product should expect to track those changes. The middle ground is worth considering as well. A separate embedded store for one bounded problem inside an application that already has a relational database, with the engine used for a hot path and the database kept for everything else, is often a better shape than migrating everything.

## Conclusion

Adopt TidesDB if you are writing a C or C++ service that needs an embeddable transactional store with real isolation levels and the option to relax durability, and you want to avoid running a separate database server. Skip it if you need a mature client ecosystem, replication, or a query language over your data, since this is a storage engine library rather than a database. Verify first which durability setting matches your data loss tolerance, how the key-value separation and column family options change your access patterns, and that the platform and architecture you target are among the ones the project lists.

## FAQ

### What is TidesDB and is it a database?

It is a transactional key-value storage engine library written in C, built on a log-structured merge-tree. The README states it is not a full-featured database but a library you can use to build a database on top of, or as a standalone key-value and column store.

### Which isolation levels and transaction features does TidesDB support?

The feature list states ACID with MVCC and an extensive transactional API with 5 isolation levels, including 2PC-XA. The README does not enumerate the five levels, so the header files and documentation are where you would find the exact set.

### How is TidesDB licensed, and what about its dependencies?

The engine is under the Mozilla Public License Version 2.0, with multiple licences applying to the dependencies. xxHash is BSD 2, and the compression codecs carry their own terms, BSD 3 Clause for Snappy, BSD 2 for LZ4 and BSD for Zstandard, and those optional licences apply only if you enable the corresponding codec.

## Sources

- [License: MPL-2.0](https://github.com/tidesdb/tidesdb/blob/master/LICENSE)
- [Project website](https://tidesdb.com)
- [README](https://github.com/tidesdb/tidesdb/blob/master/README.md)
- [Releases](https://github.com/tidesdb/tidesdb/releases)
- [tidesdb/tidesdb on GitHub](https://github.com/tidesdb/tidesdb)

---

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