Liking cljdoc? Tell your friends :D


An opinionated Clojure library wrapping Aerospike Java Client.


  • Java 8
  • Clojure 1.8


  • Converts Java client's callback model into a future (manifold/deferred) based API.
  • Expose passing functional transcoders over payloads (both put/get).
  • Health-check utility.
  • Functions return Clojure maps.


  • Non blocking only: Expose only the non-blocking API. Block with deref if you like.
  • Futures instead of callbacks. Futures (and functional chaining) are more composable and less cluttered. If a synchronous behaviour is still desired, the calling code can still deref (@) the returned future object. For a more sophisticated coordination, a variety of control mechanism is supplied by manifold/deferred.
  • Tries to follow the method names of the underlying Java API (with Clojure standard library limitations)
  • TTLs should be explicit, and developers should think about them. Forces passing a ttl and not use the cluster default.
  • Minimal dependencies.
  • Single client per Aerospike namespace.

Limitations/ caveats

  • Currently supports only single bin records.
  • Does not expose batch operations.
  • Does not support passing all Policy flags as Clojure keywords yet (WIP).


  • use batch asynchronous APIs


Most of the time just create a simple client (single cluster)

(require '[aerospike-clj.client :as client)

(def db (client/init-simple-aerospike-client
          ["", ""] "my-ns" {:enable-logging true}))

It is possible to inject additional asynchronous user-defined behaviour. To do that add an instance of ClientEvents. Some useful info is passed in in-order to support metering and to read client configuration. op-start-time is (System/nanoTime).

(let [c (client/init-simple-aerospike-client
          {:client-events (reify ClientEvents
                            (on-success [_ op-name op-result index op-start-time db]
                              (when (:enable-logging? db)
                                (println op-name "success!")))
                            (on-failure [_  op-name op-ex index op-start-time db]
                              (println "oh-no" op-name "failed on index" index)))})]

  (get-single-with-meta c "index" "set-name"))


(let [data (rand-int 1000)]
    (is (true? @(client/create db "a-key" "a-set" data 100)))
    (let [{:keys [payload gen]} @(client/get-single-with-meta db "a-key" "a-set")]
      (is (= data payload))
      (is (= 1 gen))))


Aerospike returns a TTL on the queried records that is Epoch style, but with a different "beginning of time" which is "2010-01-01T00:00:00Z". Call expiry-unix with the returned TTL to get a UNIX TTL if you want to convert it later to a more standard timestamp.


(let [data (rand-int 1000)]
    (is (true? @(client/put db "another-key" "a-set" data 100{:record-exist-action :replace :transcoder identity})))
    (let [{:keys [payload gen]} @(client/get-single-with-meta db "another-key" "a-set")]
      (is (= data payload))
      (is (= 1 gen))))

Creating additional clients

Implement IAerospikeClient. For example, creating a client that is sharding reads and writes between several clients:

(defrecord ShardedAerospikeClient [^"[Lcom.aerospike.client.AerospikeClient;" acs
                                   ^int shards
                                   ^EventLoop el
                                   ^ClientPolicy cp
                                   ^String dbns
                                   ^String cluster-name
                                   ^boolean logging?
  (get-client ^AerospikeClient [_ index] (get acs (mod (hash index) shards)))
  (get-client-policy ^ClientPolicy [_] cp)
  (get-all-clients [_] acs))


Testing is performed against a local Aerospike running in the latest docker

$ sudo docker run -d --name aerospike -p 3000:3000 -p 3001:3001 -p 3002:3002 -p 3003:3003 aerospike
$ lein test


PRs are welcome!


Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close