«

Local Dev and CI with Datomic Local

With Datomic Local you can develop and test applications with minimal connectivity and setup. Get the datomic local library, add it to your classpath, and you have full access to the client API. This allows you to:

Datomic Local is available at no cost and is Apache licensed.

This document includes everything you need to know to use Datomic Local:

Setup

Datomic Local is available on Maven. You can include it in project deps with:

com.datomic/local    {:mvn/version "1.0.277"}

Configure Local Storage

By default, datomic stores all databases under a common storage directory. To specify this directory, create a .datomic/local.edn file in your home directory, containing a map with :storage-dir and an absolute path:

{:storage-dir "/full/path/to/where/you/want/data"}

Using Datomic Local

There are two steps to use Datomic Local: add the Datomic Local library to your classpath and create a local client.

To add Datomic Local to your classpath, add a com.datomic/local entry to your deps.edn file.

{com.datomic/local
 {:mvn/version "1.0.277"}}

The Datomic Local dependency is all you need for using Datomic Local.

There are two ways to get a local client:

  • You can explicitly request a local client
  • You can divert requests for Datomic Cloud clients to use local storage for development and testing

To explicitly request a local client, pass a map to d/client with:

  • :server-type :datomic-local
  • A :system name,
(require '[datomic.client.api :as d])
(def client (d/client {:server-type :datomic-local
                       :system "dev"}))

If you are using Datomic Local to develop and test a Datomic Cloud application, add the client-cloud dependency to your project. Then, to divert an existing Datomic Cloud system to Datomic Local, call divert-system:

(require '[datomic.local :as dl])
(dl/divert-system {:system "production"})

;; existing requests for Cloud system will be served locally!
(def client (d/client {:system "production"
                       :server-type :ion
                       :region "us-east-1"
                       :endpoint "https://ljfrt3pr18.execute-api.us-east-1.amazonaws.com"}))

You can also use import-cloud to import data from Datomic Cloud to local storage.

If you are new to Datomic, you can now work through the tutorial.

Sample Data

datomic-samples is a set of databases that are used throughout these Datomic docs and the Day of Datomic tutorials. To install the Datomic samples on your local computer:

You can connect and use them by setting your Datomic Local system name to "datomic-samples":

(require '[datomic.client.api :as d])
(def client (d/client {:server-type :datomic-local
                       :system "datomic-samples"}))
(d/list-databases client {})
=> ["mbrainz-subset" "solar-system" "social-news" "movies" ...]

Durability

Datomic Local stores data to your local filesystem, in directories under the :system you specify when creating a Datomic Local client.

Each database will store transactions in a directory named <storage-dir>/<system-name>/<database-name>. You can "backup" or "restore" a Datomic Local database simply by copying the database directory.

Memdb

Sometimes durable storage is unnecessary and/or inconvenient. For example, a CI system may not need data after the tests run and no access to a file system.

You can force Datomic Local to use a memory-only database by passing :storage-dir :mem to the map you pass when creating a client, as shown in the example below:

(def client (d/client {:server-type :datomic-local
                       :storage-dir :mem
                       :system "ci"}))

Limits

  • Datomic Local is in-process with your application code, and has all the tradeoffs (vs. a server or cluster) that this implies.
  • Datomic Local requires 32 bytes of JVM heap per datom. You should plan your application with this in mind, while also leaving a memory for your application's use.
  • Datomic Local relies on OS page caching for performance, so leave some RAM is available (i.e. not allocated to the JVM heap) for this.
  • Datomic Local limits the total number of datoms in a transaction to 105.
  • Datomic Local limits strings to 4096 characters.
  • Datomic Local uses shared FileChannels. This is very efficient but is intolerant of Thread.interrupt. If you interrupt Datomic Local I/O, subsequent I/O may trigger a ClosedChannelException. Try to avoid using interrupt as a control mechanism. If you cannot, you can resume by calling release-db and reacquiring a connection.

Datomic Local is best suited for small, single-process applications. For larger projects, create a Datomic Cloud system.

Next Steps

If you are trying Datomic Local for the first time, a good next step is the client API tutorial.