DragonflyDB vs Redis

Normally, when we think of in-memory databases, Redis and Memcached often come to mind. Today, I’d like to introduce another interesting option: Dragonfly, which claims to be a multi-threaded Redis replacement. So, let’s test how Dragonfly compares to Redis 7.
Redis test compose
First, let’s create a compose file for testing Redis.
services:
redis:
image: redis
ulimits:
memlock: -1
volumes:
- redis-data:/data
hostname: redis
command:
["redis-server", "--loglevel warning", "--unixsocket", "/data/redis.sock"]
redis_tcp:
depends_on:
- redis
image: redislabs/memtier_benchmark
volumes:
- redis-data:/redis-data
- ./tmp:/data
command: ["-h", "redis", "--out-file=/data/redis-tcp.log"]
redis_sock:
depends_on:
- redis
image: redislabs/memtier_benchmark
volumes:
- redis-data:/redis-data
- ./tmp:/data
command: ["-S", "/redis-data/redis.sock", "--out-file=/data/redis-sock.log"]
volumes:
redis-data:
Dragonfly test compose
Next, the compose file for Dragonfly.
services:
dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly
ulimits:
memlock: -1
volumes:
- dragonfly-data:/data
hostname: dragonfly
command:
["dragonfly", "--logtostderr", "--unixsocket", "/data/dragonfly.sock"]
dragonfly_tcp:
depends_on:
- dragonfly
image: redislabs/memtier_benchmark
volumes:
- dragonfly-data:/dragonfly-data
- ./tmp:/data
command: ["-h", "dragonfly", "--out-file=/data/dragonfly-tcp.log"]
dragonfly_sock:
depends_on:
- dragonfly
image: redislabs/memtier_benchmark
volumes:
- dragonfly-data:/dragonfly-data
- ./tmp:/data
command: ["-S", "/dragonfly-data/dragonfly.sock", "--out-file=/data/dragonfly-sock.log"]
volumes:
dragonfly-data:
TCP
Let’s start with the common scenario where everyone uses TCP/IP between containers.
Redis
docker compose -f docker-compose.redis.yml up redis_tcp
| Type | Ops/sec | Hits/sec | Misses/sec | Avg. Latency | p50 Latency | p99 Latency | p99.9 Latency | KB/sec |
|---|---|---|---|---|---|---|---|---|
| Sets | 6446.59 | — | — | 2.82053 | 2.68700 | 5.40700 | 10.36700 | 496.50 |
| Gets | 64395.05 | 0.00 | 64395.05 | 2.82098 | 2.68700 | 5.40700 | 10.68700 | 2508.47 |
| Waits | 0.00 | — | — | — | — | — | — | — |
| Totals | 70841.64 | 0.00 | 64395.05 | 2.82093 | 2.68700 | 5.40700 | 10.62300 | 3004.97 |
Dragonfly
docker compose -f docker-compose.dragonfly.yml up dragonfly_tcp
| Type | Ops/sec | Hits/sec | Misses/sec | Avg. Latency | p50 Latency | p99 Latency | p99.9 Latency | KB/sec |
|---|---|---|---|---|---|---|---|---|
| Sets | 12683.03 | — | — | 1.53450 | 0.66300 | 10.87900 | 16.12700 | 976.82 |
| Gets | 126690.88 | 0.00 | 126690.88 | 1.51768 | 0.65500 | 10.94300 | 16.31900 | 4935.16 |
| Waits | 0.00 | — | — | — | — | — | — | — |
| Totals | 139373.91 | 0.00 | 126690.88 | 1.51921 | 0.65500 | 10.94300 | 16.31900 | 5911.97 |
UNIX socket
Now let’s try testing with UNIX sockets between containers.
Redis
docker compose -f docker-compose.redis.yml up redis_sock
| Type | Ops/sec | Hits/sec | Misses/sec | Avg. Latency | p50 Latency | p99 Latency | p99.9 Latency | KB/sec |
|---|---|---|---|---|---|---|---|---|
| Sets | 17540.93 | — | — | 1.04733 | 0.99900 | 1.82300 | 4.99100 | 1350.96 |
| Gets | 175216.52 | 0.00 | 175216.52 | 1.04597 | 0.99900 | 1.82300 | 3.87100 | 6825.44 |
| Waits | 0.00 | — | — | — | — | — | — | — |
| Totals | 192757.45 | 0.00 | 175216.52 | 1.04610 | 0.99900 | 1.82300 | 4.03100 | 8176.40 |
Dragonfly
docker compose -f docker-compose.dragonfly.yml up dragonfly_sock
| Type | Ops/sec | Hits/sec | Misses/sec | Avg. Latency | p50 Latency | p99 Latency | p99.9 Latency | KB/sec |
|---|---|---|---|---|---|---|---|---|
| Sets | 23136.83 | — | — | 0.80438 | 0.27900 | 7.74300 | 14.39900 | 1781.94 |
| Gets | 231114.05 | 0.00 | 231114.05 | 0.78618 | 0.27900 | 7.39100 | 12.67100 | 9002.89 |
| Waits | 0.00 | — | — | — | — | — | — | — |
| Totals | 254250.88 | 0.00 | 231114.05 | 0.78783 | 0.27900 | 7.42300 | 12.79900 | 10784.83 |
Conclusion
With the power of multi-threading, Dragonfly performs very well (especially through UNIX sockets, where the difference from TCP/IP is noticeable). However, it’s worth noting that Dragonfly doesn’t currently support 100% of the Redis API. If you’re using advanced or special features, you’ll need to check if it can be used as a direct replacement. You can find more information in the command-reference. From my testing, if you normally use Redis with only a single instance, and don’t use Graph or Geo location features, primarily using Set, Get, and occasionally PubSub or Stream, you can replace it with Dragonfly. The code and connection methods remain the same.