Key-value: ParticleDB and Redis
ParticleDB serves Redis clients over the Redis protocol (RESP) and its own native key-value protocol. This page compares it with Redis in two durability modes, each against the Redis setting that gives the same guarantee.
| Mode | ParticleDB | Redis | Reply sent | Writes lost on power failure |
|---|---|---|---|---|
| Asynchronous | --kv-durability async (default) |
appendfsync everysec |
Before fsync | ParticleDB: writes since the last fsync, about 1.7 ms in our tests (fsync runs continuously). Redis: up to 1 second. |
| Durable | --durability sync |
appendfsync always |
After fsync | None: every acknowledged write is on disk. |
Results at a glance
Section titled “Results at a glance”ParticleDB operations per second divided by Redis operations per second, one command per request, over RESP. Above 1.00x means ParticleDB is faster.
| Operation | Async, 8 clients | Async, 64 clients | Async, 512 clients | Durable, 8 clients | Durable, 64 clients | Durable, 512 clients |
|---|---|---|---|---|---|---|
| SET | 1.27x | 2.21x | 4.81x | 1.78x | 1.27x | 1.58x |
| GET | 1.60x | 3.13x | 7.11x | 1.56x | 3.08x | 7.04x |
| INCR | 1.46x | 3.12x | 6.88x | 1.70x | 1.08x | 1.88x |
| LPUSH | 1.49x | 3.19x | 6.45x | 1.74x | 1.12x | 1.99x |
| HSET | 1.51x | 3.05x | 5.06x | 1.75x | 1.16x | 1.91x |
ParticleDB scales with the server’s cores: throughput keeps rising as clients are added. With a single client the result is decided by per-request latency rather than cores; see the full tables.
Asynchronous mode
Section titled “Asynchronous mode”ParticleDB --kv-durability async against Redis appendfsync everysec.
- - - Redis 7.2.7 (appendfsync everysec) ━━ ParticleDB over RESP (–kv-durability async) ━━ ParticleDB native KV protocol (–kv-durability async)
The native key-value protocol, asynchronous mode, against Redis:
| Operation | 8 clients | 64 clients | 512 clients |
|---|---|---|---|
| SET | 1.64x | 2.59x | 2.97x |
| GET | 3.07x | 13.90x | 14.09x |
| INCR | 2.12x | 4.09x | 4.12x |
All asynchronous results
| Operation | Clients | Pipeline | Redis ops/s | ParticleDB RESP ops/s | ParticleDB native ops/s | p99 ms (Redis / RESP / native) |
|---|---|---|---|---|---|---|
| SET | 1 | 1 | 76,118 | 68,266 (0.90x) | 68,327 (0.90x) | 0.02 / 0.02 / 0.02 |
| SET | 8 | 1 | 184,215 | 233,152 (1.27x) | 302,244 (1.64x) | 0.08 / 0.05 / 0.03 |
| SET | 64 | 1 | 201,032 | 443,773 (2.21x) | 521,024 (2.59x) | 0.70 / 1.34 / 0.31 |
| SET | 512 | 1 | 186,393 | 897,390 (4.81x) | 553,506 (2.97x) | 5.30 / 49.43 / 58.37 |
| SET | 1 | 16 | 367,935 | 256,508 (0.70x) | 221,875 (0.60x) | 0.08 / 0.06 / 0.06 |
| SET | 8 | 16 | 704,422 | 1,011,502 (1.44x) | 884,271 (1.26x) | 0.43 / 0.20 / 0.17 |
| SET | 64 | 16 | 722,018 | 1,467,997 (2.03x) | 550,216 (0.76x) | 4.87 / 69.33 / 76.98 |
| SET | 512 | 16 | 640,440 | 1,470,331 (2.30x) | 549,610 (0.86x) | 34.05 / 182.32 / 191.79 |
| GET | 1 | 1 | 86,504 | 86,650 (1.00x) | 93,092 (1.08x) | 0.01 / 0.01 / 0.01 |
| GET | 8 | 1 | 231,070 | 368,629 (1.60x) | 708,725 (3.07x) | 0.09 / 0.08 / 0.01 |
| GET | 64 | 1 | 245,796 | 769,476 (3.13x) | 3,415,933 (13.90x) | 0.51 / 1.13 / 0.03 |
| GET | 512 | 1 | 228,156 | 1,623,240 (7.11x) | 3,214,184 (14.09x) | 2.39 / 0.89 / 0.32 |
| GET | 1 | 16 | 470,946 | 442,819 (0.94x) | 469,980 (1.00x) | 0.07 / 0.07 / 0.03 |
| GET | 8 | 16 | 1,188,489 | 1,576,930 (1.33x) | 3,439,170 (2.89x) | 0.20 / 0.18 / 0.03 |
| GET | 64 | 16 | 1,208,791 | 3,768,671 (3.12x) | 9,201,634 (7.61x) | 1.68 / 1.39 / 0.23 |
| GET | 512 | 16 | 1,086,199 | 4,474,941 (4.12x) | 9,105,514 (8.38x) | 15.17 / 8.09 / 1.93 |
| INCR | 1 | 1 | 85,211 | 75,109 (0.88x) | 76,536 (0.90x) | 0.01 / 0.01 / 0.01 |
| INCR | 8 | 1 | 232,492 | 339,363 (1.46x) | 492,904 (2.12x) | 0.04 / 0.04 / 0.02 |
| INCR | 64 | 1 | 252,751 | 788,769 (3.12x) | 1,034,431 (4.09x) | 0.49 / 1.20 / 0.26 |
| INCR | 512 | 1 | 234,974 | 1,617,664 (6.88x) | 967,861 (4.12x) | 2.29 / 0.79 / 2.92 |
| INCR | 1 | 16 | 537,361 | 436,964 (0.81x) | 346,485 (0.64x) | 0.03 / 0.04 / 0.04 |
| INCR | 8 | 16 | 1,166,854 | 2,158,263 (1.85x) | 1,690,443 (1.45x) | 0.15 / 0.13 / 0.08 |
| INCR | 64 | 16 | 1,196,083 | 4,511,391 (3.77x) | 999,519 (0.84x) | 1.56 / 0.93 / 1.79 |
| INCR | 512 | 16 | 1,140,930 | 4,523,900 (3.97x) | 1,020,847 (0.89x) | 13.37 / 5.14 / 14.75 |
| LPUSH | 1 | 1 | 82,799 | 71,288 (0.86x) | - | 0.01 / 0.02 |
| LPUSH | 8 | 1 | 211,634 | 315,153 (1.49x) | - | 0.05 / 0.04 |
| LPUSH | 64 | 1 | 224,012 | 714,908 (3.19x) | - | 0.55 / 1.29 |
| LPUSH | 512 | 1 | 207,346 | 1,337,532 (6.45x) | - | 3.49 / 0.77 |
| LPUSH | 1 | 16 | 404,925 | 309,297 (0.76x) | - | 0.06 / 0.05 |
| LPUSH | 8 | 16 | 674,187 | 1,164,057 (1.73x) | - | 0.48 / 0.16 |
| LPUSH | 64 | 16 | 670,544 | 1,451,012 (2.16x) | - | 4.14 / 1.68 |
| LPUSH | 512 | 16 | 653,771 | 1,464,682 (2.24x) | - | 31.33 / 54.53 |
| HSET | 1 | 1 | 79,416 | 70,142 (0.88x) | - | 0.01 / 0.02 |
| HSET | 8 | 1 | 199,626 | 301,992 (1.51x) | - | 0.06 / 0.04 |
| HSET | 64 | 1 | 209,798 | 639,061 (3.05x) | - | 0.59 / 1.28 |
| HSET | 512 | 1 | 195,810 | 990,884 (5.06x) | - | 3.80 / 0.92 |
| HSET | 1 | 16 | 335,565 | 257,979 (0.77x) | - | 0.08 / 0.06 |
| HSET | 8 | 16 | 522,275 | 806,361 (1.54x) | - | 0.57 / 0.28 |
| HSET | 64 | 16 | 523,017 | 873,462 (1.67x) | - | 5.34 / 4.00 |
| HSET | 512 | 16 | 512,038 | 922,858 (1.80x) | - | 38.54 / 47.45 |
| redis-benchmark mix | 1 | 1 | 81,392 | 70,718 (0.87x) | - | 0.01 / 0.01 |
| redis-benchmark mix | 8 | 1 | 176,792 | 173,568 (0.98x) | - | 0.04 / 0.04 |
| redis-benchmark mix | 64 | 1 | 174,774 | 173,086 (0.99x) | - | 0.21 / 0.22 |
| redis-benchmark mix | 512 | 1 | 164,499 | 160,419 (0.98x) | - | 1.67 / 1.93 |
| redis-benchmark mix | 1 | 16 | 672,856 | 429,642 (0.64x) | - | 0.03 / 0.04 |
| redis-benchmark mix | 64 | 16 | 1,144,916 | 870,862 (0.76x) | - | 1.07 / 3.06 |
| redis-benchmark mix | 512 | 16 | 1,136,084 | 873,683 (0.77x) | - | 11.72 / 23.86 |
Data: run of 2026-10-31 with the ParticleDB 1.1.19-rc.17 release candidate (commit 14813b4d9).
Durable mode
Section titled “Durable mode”ParticleDB --durability sync against Redis appendfsync always. Each write waits for an fsync of about 1.7 ms on this volume, which sets the single-client rate for both systems. Every ParticleDB configuration is also killed with kill -9 and every acknowledged write is verified after restart.
The native key-value protocol, durable mode, against Redis:
| Operation | 8 clients | 64 clients | 512 clients |
|---|---|---|---|
| SET | 2.23x | 1.53x | 1.73x |
| GET | 3.03x | 13.58x | 14.55x |
| INCR | 2.07x | 1.49x | 2.28x |
All durable results
| Operation | Clients | Pipeline | Redis ops/s | ParticleDB RESP ops/s | ParticleDB native ops/s | p99 ms (Redis / RESP / native) |
|---|---|---|---|---|---|---|
| SET | 1 | 1 | 572 | 1,041 (1.82x) | 1,051 (1.84x) | 2.23 / 1.83 / 1.80 |
| SET | 8 | 1 | 2,441 | 4,342 (1.78x) | 5,431 (2.23x) | 3.87 / 2.79 / 2.75 |
| SET | 64 | 1 | 27,215 | 34,605 (1.27x) | 41,727 (1.53x) | 4.68 / 4.12 / 4.02 |
| SET | 512 | 1 | 98,831 | 155,820 (1.58x) | 171,468 (1.73x) | 10.57 / 32.88 / 33.11 |
| SET | 1 | 16 | 8,704 | 16,007 (1.84x) | 15,919 (1.83x) | 2.08 / 2.30 / 1.92 |
| SET | 8 | 16 | 30,768 | 63,222 (2.05x) | 66,252 (2.15x) | 5.80 / 4.84 / 4.38 |
| SET | 64 | 16 | 224,498 | 272,784 (1.22x) | 214,271 (0.95x) | 10.90 / 60.90 / 54.18 |
| SET | 512 | 16 | 465,591 | 1,063,772 (2.28x) | 518,057 (1.11x) | 41.09 / 305.76 / 250.51 |
| GET | 1 | 1 | 87,048 | 86,873 (1.00x) | 91,153 (1.05x) | 0.01 / 0.01 / 0.01 |
| GET | 8 | 1 | 234,559 | 365,324 (1.56x) | 709,947 (3.03x) | 0.09 / 0.08 / 0.01 |
| GET | 64 | 1 | 247,115 | 762,339 (3.08x) | 3,354,919 (13.58x) | 0.50 / 1.16 / 0.03 |
| GET | 512 | 1 | 230,320 | 1,622,391 (7.04x) | 3,351,659 (14.55x) | 2.39 / 0.89 / 0.31 |
| GET | 1 | 16 | 471,989 | 441,914 (0.94x) | 462,057 (0.98x) | 0.07 / 0.07 / 0.03 |
| GET | 8 | 16 | 1,189,800 | 1,597,774 (1.34x) | 3,396,994 (2.86x) | 0.21 / 0.18 / 0.03 |
| GET | 64 | 16 | 1,207,474 | 5,453,360 (4.52x) | 9,871,788 (8.18x) | 1.66 / 1.52 / 0.21 |
| GET | 512 | 16 | 1,091,555 | 6,877,056 (6.30x) | 9,808,988 (8.99x) | 15.56 / 8.09 / 1.74 |
| INCR | 1 | 1 | 573 | 1,045 (1.82x) | 1,053 (1.84x) | 1.92 / 1.79 / 1.83 |
| INCR | 8 | 1 | 2,554 | 4,340 (1.70x) | 5,288 (2.07x) | 3.72 / 2.74 / 2.70 |
| INCR | 64 | 1 | 31,037 | 33,646 (1.08x) | 46,127 (1.49x) | 4.01 / 2.80 / 2.83 |
| INCR | 512 | 1 | 126,064 | 236,917 (1.88x) | 286,797 (2.28x) | 4.29 / 3.65 / 4.08 |
| INCR | 1 | 16 | 9,060 | 16,154 (1.78x) | 15,978 (1.76x) | 1.91 / 1.83 / 1.83 |
| INCR | 8 | 16 | 35,488 | 68,490 (1.93x) | 71,610 (2.02x) | 3.83 / 2.77 / 2.87 |
| INCR | 64 | 16 | 342,567 | 465,894 (1.36x) | 377,026 (1.10x) | 5.57 / 3.19 / 4.69 |
| INCR | 512 | 16 | 820,416 | 2,163,346 (2.64x) | 962,392 (1.17x) | 16.91 / 8.09 / 14.22 |
| LPUSH | 1 | 1 | 573 | 1,044 (1.82x) | - | 1.89 / 1.79 |
| LPUSH | 8 | 1 | 2,498 | 4,335 (1.74x) | - | 3.69 / 2.70 |
| LPUSH | 64 | 1 | 30,469 | 34,002 (1.12x) | - | 4.08 / 2.80 |
| LPUSH | 512 | 1 | 113,668 | 225,717 (1.99x) | - | 5.80 / 4.18 |
| LPUSH | 1 | 16 | 9,010 | 15,892 (1.76x) | - | 1.94 / 1.83 |
| LPUSH | 8 | 16 | 34,868 | 69,244 (1.99x) | - | 3.95 / 2.80 |
| LPUSH | 64 | 16 | 269,552 | 413,172 (1.53x) | - | 7.05 / 4.88 |
| LPUSH | 512 | 16 | 543,981 | 1,047,227 (1.93x) | - | 32.90 / 65.27 |
| HSET | 1 | 1 | 573 | 1,044 (1.82x) | - | 1.89 / 1.81 |
| HSET | 8 | 1 | 2,479 | 4,334 (1.75x) | - | 3.69 / 2.74 |
| HSET | 64 | 1 | 30,272 | 35,065 (1.16x) | - | 4.11 / 2.80 |
| HSET | 512 | 1 | 109,608 | 208,905 (1.91x) | - | 6.26 / 5.14 |
| HSET | 1 | 16 | 8,992 | 15,864 (1.76x) | - | 1.91 / 1.83 |
| HSET | 8 | 16 | 34,640 | 70,698 (2.04x) | - | 3.95 / 2.80 |
| HSET | 64 | 16 | 239,502 | 413,766 (1.73x) | - | 8.09 / 5.28 |
| HSET | 512 | 16 | 439,584 | 949,804 (2.16x) | - | 41.68 / 38.01 |
| redis-benchmark mix | 1 | 1 | 573 | 1,044 (1.82x) | - | 1.96 / 1.80 |
| redis-benchmark mix | 8 | 1 | 2,473 | 4,337 (1.75x) | - | 3.68 / 2.70 |
| redis-benchmark mix | 64 | 1 | 19,472 | 34,317 (1.76x) | - | 3.98 / 2.75 |
| redis-benchmark mix | 512 | 1 | 96,598 | 149,422 (1.55x) | - | 6.65 / 4.19 |
| redis-benchmark mix | 1 | 16 | 9,074 | 16,132 (1.78x) | - | 1.98 / 1.81 |
| redis-benchmark mix | 8 | 16 | 35,234 | - | - | |
| redis-benchmark mix | 64 | 16 | 227,207 | 373,834 (1.65x) | - | 5.33 / 5.00 |
| redis-benchmark mix | 512 | 16 | 665,599 | 779,971 (1.17x) | - | 17.61 / 25.49 |
Data: run of 2026-10-31 with the ParticleDB 1.1.19-rc.17 release candidate (commit 14813b4d9).
Test setup
Section titled “Test setup”| Machine | AWS c8g.metal-48xl, 192 Graviton4 vCPUs, 500 GB EBS data volume (4 KiB fsync median 1.73 ms) |
| CPU placement | Server pinned to 48 cores (0-47), load generator to 48 other cores (48-95) |
| Redis | 7.2.7, default io-threads (single-threaded command execution) |
| Load generators | memtier_benchmark 2.1.4, redis-benchmark 7.2.7, and the suite’s own RESP and native drivers; the same driver runs against both servers in each cell |
| Data | 100,000 keys, 32-byte values; list and hash operations spread across keys |
| Clients and pipelining | 1, 8, 64 and 512 connections; 1 and 16 commands per request |
| Statistic | Median over alternating rounds in one session; p99 latency per cell |
How to run it
Section titled “How to run it”Run each server alone on the machine, pinned to the same cores, and drive it from other cores.
1. Start Redis
Section titled “1. Start Redis”redis.conf used for both modes (change the last line to appendfsync always for durable mode):
bind 127.0.0.1protected-mode notcp-backlog 4096maxclients 20000timeout 0tcp-keepalive 0save ""aof-use-rdb-preamble yesappendonly yesappendfsync everysectaskset -c 0-47 redis-server ./redis.conf --port 6379 --dir /data/redis2. Start ParticleDB
Section titled “2. Start ParticleDB”Asynchronous mode:
taskset -c 0-47 particledb start --no-auth \ --durability groupsync --kv-durability async \ --data-dir /data/pdb --redis-addr 127.0.0.1:6379Durable mode: replace the second line with --durability sync --kv-durability sync.
3. Run the load
Section titled “3. Run the load”Each cell runs a 2-second warm-up and an 8-second timed run with the client pinned to the other cores. For example, SET with 64 clients and no pipelining:
taskset -c 48-95 memtier_benchmark -s 127.0.0.1 -p 6379 --protocol=redis \ -t 8 -c 8 --ratio=1:0 --key-pattern=R:R --key-minimum=1 --key-maximum=100000 \ -d 32 --pipeline=1 --test-time=8 --hide-histogramFor GET use --ratio=0:1 after loading the keys; for pipelining use --pipeline=16; for other client counts change -t (threads) and -c (connections per thread) so that t x c is 1, 8, 64 or 512. The classic mix uses the stock tool:
taskset -c 48-95 redis-benchmark -h 127.0.0.1 -p 6379 -c 64 -P 1 -d 32 -r 100000 -n 1000000 \ -t set,get,incr,lpush,hset --csvThe results on this page were produced by our benchmark suite, which runs the same cells with a verifying load driver: it checks every reply and the final state of the keys, alternates Redis and ParticleDB rounds in one session, and kills each ParticleDB configuration with kill -9 to confirm that acknowledged writes survive. The native-protocol rows use the same driver over the ParticleDB native key-value protocol.
4. Report
Section titled “4. Report”Use the median of the timed rounds per cell, with p99 latency, and publish the server versions, configuration and machine details listed under Test setup.
See Benchmarks and methodology for the reporting rules.
This site uses Google Analytics cookies to count visits. Privacy · License