Benchmarks
Performance comparison against Redis, DragonflyDB, and DiceDB.
Test Setup
- Hardware: 6-core Intel i5-11400H (12 hardware threads)
- Network: Loopback TCP (127.0.0.1)
- Clients: 100 concurrent connections
- Operations: 1M total (10K per client)
- FyroDB: 1 node
- Redis: 6-node Redis Cluster (7 containers)
- Pipeline: 100 commands per batch
- Pub/Sub: 50 subscribers, 10 publishers, 200K messages, pipeline 200
All tests run with the same Go benchmark tool. Best of three runs.
KV Throughput
| Metric | FyroDB | Redis Cluster (6 nodes) | DragonflyDB | DiceDB (1 node) |
|---|---|---|---|---|
| Pipeline-64 SET | 8.95M | 5.75M | 4.09M | 766K |
| Pipelined SET | 20.08M | 7.56M | 4.16M | 1.62M |
| Pipelined GET | 28.16M | 11.29M | 4.09M | 1.88M |
Pipeline-64 SET · empty → 1M keys
M ops/sec
SET throughput · pipeline 100
M ops/sec
GET throughput · pipeline 100
M ops/sec
Mixed Workload Throughput
| Metric | FyroDB | Redis Cluster (6 nodes) | DragonflyDB | Speedup |
|---|---|---|---|---|
| Mixed SET/GET (50/50) | 20.90M | 7.24M | 5.15M | 2.9× |
| INCR (counters) | 50.11M | 6.32M | 6.84M | 7.9× |
| HSET/HGET (sessions) | 33.07M | 7.95M | 5.81M | 4.2× |
| LPUSH/RPOP (queue) | 39.26M | 7.19M | 6.23M | 5.5× |
| SADD (per-client sets) | 27.87M | 6.34M | 5.00M | 4.4× |
| ZADD (per-client zsets) | 18.12M | 4.55M | 4.36M | 4.0× |
| JSON.SET/GET (docs) | 14.91M | 3.38M | 151.5K | 4.4× |
| SET+EXPIRE (cache TTL) | 10.51M | 2.64M | 2.41M | 4.0× |
| Hot Key (contention) | 44.07M | 2.03M | 2.15M | 21.7× |
| Producer/Consumer | 36.20M | 981.3K | 1.75M | 36.9× |
Mixed SET/GET (50/50)
M ops/sec
INCR · atomic counters
M ops/sec
HSET/HGET · sessions
M ops/sec
LPUSH/RPOP · queue
M ops/sec
SADD · per-client sets
M ops/sec
ZADD · per-client zsets
M ops/sec
JSON.SET/GET · documents
M ops/sec
SET+EXPIRE · cache TTL
M ops/sec
Hot Key · 1 key, contention
M ops/sec
Producer/Consumer · 50+50
M ops/sec
Pub/Sub Throughput
| Metric | FyroDB | Redis Cluster (6 nodes) | DragonflyDB | DiceDB (1 node) |
|---|---|---|---|---|
| Publish ops/sec | 1.49M | 147.1K | 315.5K | 167.8K |
| Delivery msg/sec | 74.64M | 7.35M | 15.43M | 8.39M |
Pub/Sub publish throughput
M ops/sec
Pub/Sub delivery throughput
M msg/sec
Resource Usage
Measured over the full benchmark suite across all processes.
| Metric | FyroDB (1 node, PID 2258) | Redis Cluster (6 nodes, 7 containers) | DragonflyDB (1 node) |
|---|---|---|---|
| Peak RSS | 294.19 MB | 767.63 MB | 235.80 MB |
| Avg RSS | 168.81 MB | 347.46 MB | 171.86 MB |
| Peak CPU | 79.6% | 442.1% | 957.5% |
| Avg CPU | 42.5% | 125.2% | 430.6% |
Peak RSS · lower is better
MB
Avg CPU · lower is better
% of one core
Two things worth reading carefully:
- The DragonflyDB numbers are freshly measured for this release as a single multi-threaded node on the same 6-core/12-thread machine; the DiceDB column is an earlier measurement carried over and was not re-run, so treat it as indicative.
- DragonflyDB is a single multi-threaded process, so it is the closest single-node comparison to a single FyroDB node. It uses every core at once (peak CPU 957.5%) yet FyroDB still delivers higher throughput on every workload while using a fraction of the CPU. See Production Tips.
Why FyroDB Is Faster
| Factor | Redis | DragonflyDB | FyroDB |
|---|---|---|---|
| Threading | Single-threaded | Multi-threaded (shared-nothing) | Thread-per-core (one epoll loop per CPU) |
| Hash map | Custom, single-thread | Dash (lock per segment) | Lock-free sharded map with EBR |
| Writes | In-place (single thread) | Lock + copy | Per-key spinlock, in-place, no clone |
| Reads | Single thread | Lock per segment | Wait-free via seqlock + EBR |
| Value access | Copy | Copy | Zero-copy GET (direct to TCP buffer) |
| Pub/Sub | Single-thread fan-out | Thread-per-connection | Lock-free Arc snapshot, per-CPU delivery |
| Hash probe | Deref entry per step | Segment scan | Hash tag in the slot pointer rejects non-matches without a deref |
| Hot key | Serialized by design | Lock per segment | Reads never lock; writers back off then yield |
| Cluster | 16384-slot array | n/a | Shared flat routing table, version-checked per connection |
Run Your Own Benchmark
The benchmark tool lives in the repository, so start from a clone:
git clone https://github.com/Rana718/FyroDB && cd FyroDB/bench
go run . # Full (KV + Pub/Sub + Mixed)
go run . -m key # KV only
go run . -m pub # Pub/Sub only
go run . -m mix # Mixed workloads only
go run . -p 6379 # Against Redis
go run . -cluster addr1,addr2,... # Against a clusterThe clone also ships shortcuts that start each side with a matched core count and
tear it down again. Run task --list inside it to see them; the cluster ones are
redis-up-12 / bench-redis-cluster-12 and fyro-up / bench-fyro-cluster-12,
plus 6-core equivalents without the -12 suffix.
Reproducing these numbers depends on details that are easy to get wrong, so the
committed Redis compose files pin one master per core, disable persistence, use
host networking so no NAT hop sits on the critical path, and assign slot ranges
that match the harness's own key-to-node mapping. Without that last part a handful
of boundary slots get sent to the wrong node and the harness treats the resulting
MOVED as fatal.
| Flag | Default | Description |
|---|---|---|
-p | 8000 | Server port |
-m | all | Mode: all, key, pub, mix |
--cluster | Comma-separated cluster addresses |