Open-source project
datalevin/datalevin avatar
datalevin/datalevin

Datalevin: A Clojure Datalog Database on LMDB Storage

A simple, fast and versatile Datalog database

1,477 stars87 forksClojureEPL-2.0

At a glance

What is it?
Datalevin puts a Datomic-style Datalog query engine on a fork of LMDB, with no history retention and ACID transactions. Here is what the repository documents, what it leaves open, and who should pick it over Datahike or Datomic.
Who is it for?
Adopt Datalevin if you want Datomic-flavored Datalog with ordinary delete semantics, EDN storage and an embedded footprint, and you are willing to depend on a project whose last push was 2026-09-15 and whose bus factor is one author. Do not adopt it if you need immutable history, as-of queries or audit trails, because the README states plainly that deleted data is gone; Datomic is the right tool there.
Can I use it commercially?
Yes, with conditions. EPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Clojure, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Datalevin Solves, and For Whom

The README states the rationale directly: a simple, fast, versatile and open source Datalog query engine running on durable storage. The project's own observation is that many developers prefer the Datalog flavor popularized by Datomic over SQL once they use it, because Datalog is more declarative and composable, with automatic implicit joins as the feature that wins people over. Recursive rules make it usable for graph queries and deductive reasoning, and the repository carries benchmark directories for LDBC-SNB and openrulebench to that end.

The intended audience is narrower than the tagline suggests. Datalevin is written in Clojure, and the README calls out native EDN data capability as beneficial for Clojure programs. If you are not in the Clojure ecosystem, the Java, Python and Node.js bindings exist, but the documentation surface is thinner there. The project also positions itself against Datomic on semantics, not features: it keeps deletes permanent and follows ordinary ACID behavior instead of Datomic's temporal model. That is a deliberate subtraction. If you have ever explained to a colleague why a deleted row still appears in a historical query, Datalevin's answer is that it will not.

The Mechanism: Datalog Queries Over a Forked LMDB

The storage layer is the part worth understanding first. Datalevin sits on a fork of LMDB maintained at github.com/huahaiy/dlmdb, chosen for high read performance. On top of that it adds write-ahead logging and asynchronous transactions, which the README says lets it handle write-intensive workloads. A cost-based query optimizer replaces naive clause ordering, and the README claims query performance competitive with PostgreSQL, SQLite and Neo4j. Those are the project's own benchmark claims in benchmarks/JOB-bench and benchmarks/LDBC-SNB-bench; treat them as claims until you run your own workload.

Beyond the core engine, the same storage supports several data models. Documents under 2 GiB can be stored with automatic index construction by path for JSON, EDN and Markdown, which the README compares to MongoDB or a PostgreSQL JSONB column. Vector search comes from integrating the usearch library, which is SIMD accelerated. Full-text search is a hand-written engine benchmarked in benchmarks/search-bench. There is also an MCP server and in-database embedding and text generation via llama.cpp, which is what the ai-native topic refers to. Each of these is a separate subsystem with its own documentation file, so the breadth is real but the depth per subsystem is something you should check per use case.

Deployment is three-shaped. As a library it embeds like SQLite. As a server it runs in client/server mode on default port 8898, with a Raft consensus cluster option and role-based access control. As a babashka pod it can be used for shell scripting. The same database therefore spans a single-process app and a replicated cluster, which is unusual at this size.

Installing Datalevin and Running a First Datalog Query

The README points to doc/install.md for installation and says Datalevin is simple to add as a dependency to a project written in Java, Python and the other supported bindings. That page is where the concrete dependency coordinates live, and the README does not reproduce them in the body text, so read it before you edit your project file. The Clojars badge in the README names the artifact as datalevin, and the most recent release listed in the repository is 1.1.0.

The README does give a full query example, which is the fastest way to see the shape of the API. It is a vector of :find, :in and :where clauses, passed a database value and a year parameter.

Clojure
(d/q '[:find  ?name ?total
       :in    $ ?year
       :where [?sales :sales/year ?year]
              [?sales :sales/total ?total]
              [?sales :sales/customer ?customer]
              [?customer :customers/name ?name]]
      (d/db conn) 2026)

What you should see is a set of tuples of customer name and sales total for the given year. The join on ?customer happens without you writing a join clause, which is the composability argument in miniature. Note that the example assumes you already have a connection and a schema with those attributes; the README does not show the connection setup in the snippet, so read doc/install.md and the cljdoc API pages for the full sequence. For other languages, the README links separate binding READMEs under examples/java, bindings/python and bindings/javascript, and the published artifacts are org.datalevin/datalevin-java on Maven Central, datalevin on PyPI and datalevin-node on npm.

Where Datalevin Is the Wrong Tool

The biggest limitation is stated by the project itself, not discovered by a reviewer. Datalevin deliberately drops Datomic's temporal model. When data are deleted, they are gone. There is no as-of query, no immutable log of past states, no audit trail you can reconstruct later. The README frames this as simplicity and familiarity, and for most CRUD applications it is the right call. But if your domain is finance, healthcare or anything with a retention requirement, this is a disqualifying property, and no amount of query performance compensates for it. Datomic exists for exactly that case, and the README links a critique of Datomic's temporal semantics as background, which tells you the author has thought about the trade-off rather than overlooked it.

The second limitation is maturity and bus factor. The repository's last push was 2026-09-15, and the release history shows 1.1.0 on 2026-09-03 after 1.0.1 and 1.0.2 in August 2026. That is a fast-moving 1.x line, not a decade-old storage engine. The storage layer is a personal fork of LMDB rather than upstream LMDB, which means durability and recovery behavior depend on that fork being maintained. The repository contains a fuzz directory and a jepsen directory, which suggests the author takes correctness testing seriously, but the README does not document rollback procedures, backup and restore workflows, or a migration path between versions. If your operational requirements include documented disaster recovery, you will be writing that documentation yourself.

Third, the breadth is a double-edged property. Vector search, full-text search, document indexing, MCP serving and in-database inference are all listed as features. Each is documented in its own file under doc/, and each is presumably less battle-tested than the core Datalog engine. If you need a serious vector database, a dedicated one will have more tuning knobs and more production mileage. Datalevin's advantage is having them in one process with one transaction boundary, not having the best version of each.

Datalevin Against Datahike and Datomic

The comparison people actually search for is Datalevin versus Datahike, and the two share more than they differ. Both are Clojure Datalog databases with Datomic-inspired query syntax, both are open source, and both are attempts to give Clojure developers the query model without Datomic's licensing. The difference is in the storage engine and the philosophy around it. Datalevin builds on a fork of LMDB and emphasizes raw read performance plus write-ahead logging for write-heavy workloads, with a cost-based optimizer doing the clause planning. Datahike's storage is pluggable, which trades some of that single-engine tuning for flexibility in where data lives. If your deciding factor is the storage backend, Datahike gives you a choice and Datalevin gives you one well-tuned answer.

Against Datomic the split is semantic rather than technical. Datomic keeps history as a first-class feature: the database is a value, and past values remain queryable. Datalevin keeps the query language and discards the time model. That makes Datalevin easier to reason about if you come from a relational background, and it makes Datomic the only option if you need to answer what the database looked like last Tuesday. The README also notes that Datalevin follows widely accepted ACID principles rather than introducing unusual semantics, and links a Jepsen analysis of Datomic as the contrast. Whether you find that framing fair depends on whether you consider Datomic's semantics unusual or correct.

A third reference point is SQLite, which the README invokes for the embedded use case. The difference there is the query language, not the deployment shape. Both are single-file, in-process, transactional stores. Datalevin's argument is that Datalog's implicit joins and recursive rules express graph-shaped questions that SQL handles awkwardly. If your data is genuinely tabular and your team knows SQL, that argument is weaker.

Licence and the Cost of Upgrades

Datalevin is licensed under EPL-2.0, the Eclipse Public License 2.0. That is a file-level copyleft licence with a patent grant, and it is the same licence family used across much of the Clojure ecosystem, so it should be unremarkable for most users. The point that deserves attention is the LMDB fork at github.com/huahaiy/dlmdb. The README describes it as our fork, and it is a separate repository with its own licence file. Before you ship, read that licence, because your dependency graph includes it whether or not you name it directly. This is not legal advice; if the distinction between EPL-2.0 and the fork's terms matters to your organization, ask someone qualified.

Upgrade cost is the other budget line. The release cadence visible in the repository is 1.0.1 on 2026-08-11, 1.0.2 later the same day, and 1.1.0 on 2026-09-03. A minor version bump in that window suggests API surface is still moving. The README does not document a compatibility policy, a deprecation process or a migration guide between versions, so pinning an exact version in your dependency file is the practical approach. The repository does carry a CHANGELOG.md at the top level, which is where you should look before upgrading. Because the storage engine is a fork, an upgrade may also change on-disk format, and the README does not document a backup and restore path that would let you move a database between versions safely.

Editorial conclusion

Adopt Datalevin if you want Datomic-flavored Datalog with ordinary delete semantics, EDN storage and an embedded footprint, and you are willing to depend on a project whose last push was 2026-09-15 and whose bus factor is one author. Do not adopt it if you need immutable history, as-of queries or audit trails, because the README states plainly that deleted data is gone; Datomic is the right tool there. Before committing, verify the licence terms of the LMDB fork at github.com/huahaiy/dlmdb, check that doc/install.md covers your language binding, and confirm the 8898 default port and RBAC settings in doc/server.md match your deployment.

Frequently asked questions

Is Datalevin a replacement for Datomic?

It replaces the query language and the Datalog programming model, not the temporal data model. The README states that when data are deleted in Datalevin they are gone, whereas Datomic keeps history as a first-class feature.

Does Datalevin keep a history of changes?

No. The README says Datalevin behaves the same way as most other databases: when data are deleted, they are gone, and it follows ACID principles instead of Datomic's temporal semantics.

What languages can use Datalevin?

For embedded usage the README lists Java, Python, Node.js and Clojure, with artifacts published as org.datalevin/datalevin-java on Maven Central, datalevin on PyPI, datalevin-node on npm and datalevin on Clojars. It can also run as a babashka pod for shell scripting.

Official sources

  1. datalevin/datalevin on GitHub
  2. License: EPL-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes