Datahike SQLite Backend

SQLite storage backend for Datahike, the open datalog database.

doc status: experimental

This library provides a backend for Datahike using SQLite as the backing store, with direct native integration through sqlite4clj.

Project status: Experimental.

Why sqlite4clj?

Unlike the datahike-jdbc backend, this implementation uses sqlite4clj - a minimalist FFI binding to SQLite’s C API using Java 22’s Foreign Function Interface (Project Panama). This approach offers several advantages:

  • Bypasses JDBC overhead by interfacing directly with SQLite’s C API through FFI for direct SQLite access.

  • SQLite’s embedded nature doesn’t require thread-backed connection pools like c3p0/HikariCP, eliminating that complexity.

  • Provides better performance through cached prepared statements per connection and inline caching of column reading functions.

  • Eliminates dependencies on sqlite-jdbc, c3p0, and next.jdbc for a smaller footprint.

  • Easier access to SQLite-specific features and pragmas for targeted optimizations.

  • More suitable architecture for SQLite’s single-writer, multiple-reader model.

Installation

Include the library in your deps.edn:

 io.replikativ/datahike   {:mvn/version "0.7.1624"} ;; Use latest 0.7.x version
 ramblurr/datahike-sqlite {:git/url "https://github.com/ramblurr/datahike-sqlite"
                           :git/sha "c94e449be351b13c7b279d39ee3266cc22dd8f7d"}

Dependencies

  • The io.replikativ/datahike dependency must be provided by your project and must be 0.7.x or greater

  • sqlite4clj requires Java 22 or later.

  • If you use this library as a git dependency, you will need to prepare the library with clj -X:deps prep.

  • You must include :jvm-opts ["--enable-native-access=ALL-UNNAMED"] in your deps.edn alias.

  • When creating an executable jar file, you can avoid the need to pass this argument by adding the manifest attribute Enable-Native-Access: ALL-UNNAMED to your jar.

Example

(require
 '[datahike-sqlite.core] ;; required to pull in the multi-method implementations
 '[datahike.api :as d])

(def cfg {:store {:backend :sqlite
                  :dbname  "foobar.sqlite"
                  ;; required by modern konserve/datahike
                  :id #uuid "550e8400-e29b-41d4-a716-446655440000"
                  ;; see sqlite4clj.core/init-db! for the possible options
                  :sqlite-opts {:pool-size 4}}})

(d/database-exists? cfg)
;; => false

(d/create-database cfg)

(def conn (d/connect cfg))

(d/transact conn [{:db/ident       :artifact
                   :db/valueType   :db.type/string
                   :db/cardinality :db.cardinality/one}
                  {:db/ident       :level
                   :db/valueType   :db.type/long
                   :db/cardinality :db.cardinality/one}])

(d/transact conn [{:artifact "Mighty Teapot" :level 20}])

(d/q '[:find (pull ?e [*])
       :in $ ?artifact
       :where [?e :artifact ?artifact]]
     @conn "Mighty Teapot")


(d/release conn)

;; this will delete the table in the sqlite file,
;; but will not delete the sqlite file itself
(d/delete-database cfg)

Configuration

The value for :store is a configuration map. To invoke datahike-sqlite (this library) you must include :backend :sqlite in that map.

You must also include :dbname, a path to the SQLite file.

Konserve 0.9 and newer Datahike releases require a UUID under :id. Use a stable UUID literal in your store config.

You can optionally include the key :sqlite-opts with an options map which will be passed to sqlite4clj.core/init-db!.

Development

Benchmarking

The SQLite KV benchmark suite lives in bench/datahike_sqlite/kv_benchmark.clj.

Run the full suite with:

clojure -M:dev:bench -m datahike-sqlite.kv-benchmark

Run a smaller smoke benchmark with:

clojure -M:dev:bench -m datahike-sqlite.kv-benchmark '{:mode :smoke}'

Run the suite at a specific entry count with:

clojure -M:dev:bench -m datahike-sqlite.kv-benchmark 1000

Write the benchmark results to a file with:

clojure -M:dev:bench -m datahike-sqlite.kv-benchmark '{:n 1000 :output "bench/results/sqlite-kv.txt"}'

Testing

bb test

Formatting

bb fmt

Linting

bb lint

License: MIT License

Copyright © 2025 Casey Link casey@outskirtslabs.com

Distributed under the MIT, like dathike.