Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Redis client library for clojure
Java Clojure
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


This is a Clojure client lib for Redis

Here be dragons! .. or rather, Java. The client is a small core of java that implements the Redis protocol with a clojure API for Redis commands around it.


WORK IN PROGRESS! I expect to have a stable release in a couple of weeks, but things seems to work ok.


  • Pretty fast. The core Java part is in the same ballpark as redis-bench
  • Commands are generated from redis-doc (commands.json). This means it's easy to keep the client up-to-date with Redis development. Also, useful documention for command fns!
  • All commands are pipelined by default and returns futures.
  • Futures return can be deref:ed with (deref xx) and @ (returns Reply)
  • Replies can alse be deref:ed to their underlying values @@(ping db) => "PONG"
  • Return values are processed as little as possible, eg. @@(get db "xxx") returns byte[]. Includes some helper fns for converting to String (->str @(get r "xxx")) and String[] (->strs)
  • Sane pub/sub support, including correct behavior for UNSUBSCRIBE returning connection to normal state.
  • Support for MULTI/EXEC and return values (see example below).
  • labs-redis does not use global *bindings* for the connection ref (as in clj-redis and redis-clojure). In my target code for this library talks to alot of different Redis instances and (with-connection (client) (set key val)) adds alot of uneccesary boilerplate for us.
  • Idiomatic support for EVAL. defeval handles caching of lua source per connection and EVALSHA use etc. (defeval my-echo [] [x] "return'ECHO',ARGV[1])")
  • Small connection pool impl (pool and with-pool macro.) Work in progress..

Basic Usage

(require '[labs.redis.core :as redis])

(def db (redis/client))

(redis/ping db)
=> <ReplyFuture <StatusReply "PONG">>

@(redis/ping db)
=> <StatusReply "PONG">

(redis/value @(redis/ping db))
=> "PONG"

@@(redis/ping db)
=> "PONG"

@(redis/set db "foo" "bar")
=> <StatusReply "OK">

@(redis/get db "foo")
=> <BulkReply@xxxx: #<byte[] [B@xxxx]>>

@@(redis/get db "foo")
=> #<byte[] [B@xxxx]>

(String. @@(redis/get db "foo"))
=> "bar"

(redis/->str @(redis/get db "foo"))
=> "bar"

Arguments to commands are converted and flattened in a do-what-I-mean style, so we can write code like

;; ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
(zunionstore r "out" 2 ["set1" "set2"] {:weights [10 20] :aggregate :sum})


(defn example-subscribe-with [db]
  (subscribe-with  db
   ["msgs" "msgs2" "msgs3"]
   (fn [db channel message]
     (let [message (->str message)]
       (println "R " channel message)
       (when (= "u" message)
         (cmd** db "UNSUBSCRIBE" [channel]))
       (not (= "quit" message))))))


  ;; multi/exec with sane handling of return values
    (multi r)
    (let [_ (mset r "k1" "v1" "k2" "v2")
          a (mget r "k1" "k2")
          b (set r "k1" "xx")]
      (exec! r)
      (println (->str @a) (->str @b))) ;; xx v2
    (catch Throwable t
      (try @(discard r)
           (finally (throw t)))))

There is also a macro (atomically db &body) that does multi/exec/discard and return the MultiBulkReply from EXEC. See source for details.

What's missing


Installation / Leiningen

Not deployed on clojars yet. Install locally or use leiningen checkouts

Add [labs-redis "0.1.0"] in your project.clj then run lein deps.


Andreas Bielk :: :: @wallrat


Copyright © 2012 Andreas Bielk

Distributed under the MIT/X11 license; see the file LICENSE.

Something went wrong with that request. Please try again.