Bring immutability to your database.
Data changes. History should not.
Datomic is the free database built on immutable values, designed for a complete audit trail and queries over any past state.
Build to remember
Datomic is for systems that can't afford to forget. It shines when provenance, decision tracing, and as-of queries are central design requirements that can’t be retrofit.
Systems where the past is part of the contract
Ledgers, settlement pipelines, and compliance systems don't just ask what the current state is. They ask what was true as of specific moments in the past. Datomic stores facts instead of overwriting them, so point-in-time queries are first-class operations rather than forensic reconstruction.
- Reconstruct any past state without separate audit infrastructure
- Audit logs and operational records stay in sync
- First-class transactions attach context to every fact: who, when, why
Tracing what happened and why
When a workflow reaches an unexpected state, how it got there is your first question. With Datomic root-cause analysis happens in the database, not sifting through logs.
Supply Chain · LogisticsWho knew what, when?
In domains where documentation is evidence, corrections must be additive, not destructive. In Datomic, facts like treatment records, consent forms, and regulatory filings are amended without losing record of the past.
Healthcare · LegalFlexible data modeling
Datomic adapts to fit your data in whatever shapes make sense, without worry of impedance mismatch.
One database
Let your data be graph-structured or a hierarchy, row- or column-oriented, rich or sparse. Multiple covering indexes mean the right read-access pattern will be efficient.
Many indexes
- EAVT — “row” lookups: everything known about an entity
- AEVT — “column” scans: every value for an attribute
- AVET — k/v and range lookups: find entities by attribute value
- VAET — hierarchical traversal: walk reference attributes backwards from a value
- Pull queries express document- and graph-shaped reads over the same indexes
Decoupled scaling
Datomic’s “deconstructed” Peer/Client model enables horizontal query scaling without impact on other queries or your transaction throughput.
Storage
A pluggable, durable service, not tied to any one compute node.
Query
Local to your application with immutable database snapshots.
Transactor
Handles writes — one point of truth for the transaction log.
Architectural primitives, not workarounds.
Built in Clojure
Persistent data structures, functional transactions, open data modeling, and a commitment to stability over breaking changes. As you’d expect from a Clojure system.
Immutable
Writes append facts instead of overwriting rows, so every past database value remains available for query, debug, and replay.
Natively distributed
Built from first principles as a distributed system. Tools like d/sync and the transaction report queue make it simple to build event sourcing and deal with propagation delay.
First-class history
Past states as first-class values. Audit trails, temporal queries, and point-in-time reads are all built in, not bolted on.
Reified transactions
First-class transaction entities enables querying your database’s history itself. Change data capture, out of the box.
E/A/V+T model
A triplestore-like information model allows tabular, graph, document, sparse, and hierarchical data to coexist without impedance mismatch.
Queries across time, made trivial
First-class transactions and immutable database values make "as of the time" searches simple.
(defn top3 [db] ; top 3 planets by moon count
(->> (d/q '[:find ?name (count ?m)
:where [?p :body/kind :planet]
[?p :body/name ?name]
[?m :moon/orbits ?p]] db)
(sort-by second >)
(take 3)))
;; Across time:
(map top3 [(d/as-of db #inst "1979-12-31")
(d/as-of db #inst "1999-08-01")
db]) ; today
;; +------------+------------+-------------+------------+
;; | Date | 1st place | 2nd | 3rd |
;; +------------+------------+-------------+------------+
;; | 1979-12-31 | Jupiter 16 | Saturn 11 | Uranus 5 |
;; | 1999-08-01 | Uranus 21 | Saturn 18 | Jupiter 16 |
;; | today | Saturn 291 | Jupiter 108 | Uranus 29 |
;; +------------+------------+-------------+------------+
;; Every moon discovered in 2023 -- just ask the log.
(d/q '[:find ?inst (count ?moon)
:in $ ?log ?t1 ?t2
:where [(tx-ids ?log ?t1 ?t2) [?tx ...]]
[(tx-data ?log ?tx) [[?moon]]]
[?moon :body/kind :moon]
[?tx :db/txInstant ?inst]]
(d/db conn) (d/log conn)
#inst "2023-01-01" #inst "2024-01-01")
;; => [[#inst "2023-02-06" 12]
;; [#inst "2023-05-01" 62]
;; [#inst "2023-05-23" 1]]
;; What caused that buggy blip in our Uranus reports?
;; The query is fine with the latest data...
(d/q '[:find ?date ?citation
:in $ ?uranus
:where [?moon :moon/orbits ?uranus _ false] ; retracted at some point
[?moon _ _ ?tx]
[?tx :db/txInstant ?date]
[?tx :source/citation ?citation]]
(d/history db) [:body/name "Uranus"])
;; There's the bad data -- we were missing a moon for a couple years.
;;
;; | Date | Event |
;; +------------+----------------------------------------------+
;; | 1999-05-18 | Identified in reprocessed Voyager 2 imagery |
;; | 2001-12-20 | IAU/MPC retracts it — no confirmable orbit |
;; | 2003-09-03 | Hubble independently recovers the object |
;; | 2005-12-29 | Named Perdita, IAU announcement |
;; +------------+----------------------------------------------+
;; Which transaction contains the greatest number of Saturn's moons?
(->> (d/q '[:find ?instant (count ?moon) ?citation ?url
:keys date num-moons-discovered citation url
:where [?saturn :body/name "Saturn"]
[?moon :moon/orbits ?saturn]
[?moon _ _ ?tx-entity] ; query the actual transaction
[?tx-entity :db/txInstant ?instant]
[?tx-entity :source/url ?url]
[?tx-entity :source/citation ?citation]]
(d/history db))
(sort-by :num-moons-discovered)
last)
;; => {:num-moons-discovered 62,
;; :date #inst "2023-05-01T00:00:00.000-00:00",
;; :url "https://iopscience.iop.org/article/10.3847/2515-5172/adbf87",
;; :citation "Ashton/Gladman/Alexandersen/Beaudoin, CFHT
;; 'shift-and-stack' technique, from 2019-2021 imaging
;; — 64 candidates, 62 confirmed as genuine moons"}