Benchmarks
PostRESP vs Valkey throughput across durability modes — results, trade-offs, and how to reproduce.
PostRESP can look very different depending on how durable you ask Postgres to
be. These benchmarks compare throughput and latency against Valkey under
matched durability pairings, using the same redis-benchmark flags on both
sides.
The headline question is not “is PostRESP as fast as Redis?” — it is what do you pay, in ops/s, for each storage / durability choice?
What we measure
Default tests: PING (RESP array), SET, and GET.
| Knob | What it represents |
|---|---|
| Clients / pipeline | Concurrent load shape (redis-benchmark) |
| Storage mode (PostRESP) | Where keys live and how durable writes are |
| Persistence mode (Valkey) | None / RDB / AOF-everysec / AOF-always |
Numbers below come from an end-to-end containerized run on a shared cloud VM. Use ratios within a run to compare modes; absolute ops/s are not a hardware-independent product claim.
Durability trade-offs
Think in pairings — closest available semantics, not identical guarantees:
| Pairing | PostRESP | Valkey | When to care |
|---|---|---|---|
| Volatile SQL | unlogged — no table WAL; survives clean restart |
none |
Shared SQL storage without crash durability |
| Bounded loss | logged-async — WAL, commit returns before flush |
aof-everysec |
Accept ~1s loss window for more throughput |
| Synchronous durable | logged — commit waits for durable WAL |
aof-always |
Closest crash-durability comparison |
| Mode | Persistence behavior |
|---|---|
pg_resp/unlogged |
No table WAL; survives clean restart, may truncate after crash |
pg_resp/logged-async |
WAL-logged, commit returns before WAL flush |
pg_resp/logged |
WAL-logged; commit waits for durable WAL |
valkey/none |
No RDB or AOF |
valkey/rdb |
Periodic snapshots; AOF off |
valkey/aof-everysec |
AOF with ~1s loss window |
valkey/aof-always |
AOF fsync before reply |
Prefer unlogged when you want shared SQL storage. Use logged when you need crash recovery or Postgres replication. See Storage modes.
Latest PostRESP benchmark
Published 2026-08-03 from commit e531da36aea6: 2 repetitions, 20,000 requests/test, 20 clients, pipeline 1, 4 vCPUs.
This is an end-to-end containerized snapshot on a shared cloud VM. Use the ratios to compare modes within this run; do not treat the absolute throughput as a hardware-independent product claim.
Approximate durability pairings
| Durability pairing | PostRESP ↔ Valkey | SET ops/s (PG / VK) | SET ratio | SET avg ms (PG / VK) | GET ops/s (PG / VK) | GET ratio | GET avg ms (PG / VK) |
|---|---|---|---|---|---|---|---|
| Volatile | pg_resp/unlogged ↔ valkey/none |
28,928 / 140,547 | 0.21× | 0.671 / 0.105 | 36,416 / 148,701 | 0.24× | 0.524 / 0.102 |
| Bounded loss (approx.) | pg_resp/logged-async ↔ valkey/aof-everysec |
28,674 / 120,512 | 0.24× | 0.677 / 0.140 | 37,252 / 146,617 | 0.25× | 0.516 / 0.101 |
| Synchronous durable | pg_resp/logged ↔ valkey/aof-always |
21,945 / 42,646 | 0.51× | 0.893 / 0.450 | 37,396 / 149,287 | 0.25× | 0.516 / 0.099 |
Pairings are semantic approximations rather than identical guarantees. In particular, a short RDB run may complete without a snapshot firing.
Full matrix
| Test | Configuration | Median ops/s | Min–max ops/s | Median average latency (ms) | Repetitions |
|---|---|---|---|---|---|
| GET | pg_resp/unlogged |
36,416 | 35,587–37,244 | 0.524 | 2 |
| GET | pg_resp/logged-async |
37,252 | 36,697–37,807 | 0.516 | 2 |
| GET | pg_resp/logged |
37,396 | 36,697–38,095 | 0.516 | 2 |
| GET | valkey/none |
148,701 | 148,148–149,254 | 0.102 | 2 |
| GET | valkey/rdb |
149,387 | 144,928–153,846 | 0.098 | 2 |
| GET | valkey/aof-everysec |
146,617 | 142,857–150,376 | 0.101 | 2 |
| GET | valkey/aof-always |
149,287 | 147,059–151,515 | 0.099 | 2 |
| PING_MBULK | pg_resp/unlogged |
124,339 | 105,820–142,857 | 0.138 | 2 |
| PING_MBULK | pg_resp/logged-async |
149,815 | 149,254–150,376 | 0.105 | 2 |
| PING_MBULK | pg_resp/logged |
152,093 | 151,515–152,672 | 0.094 | 2 |
| PING_MBULK | valkey/none |
136,691 | 118,343–155,039 | 0.120 | 2 |
| PING_MBULK | valkey/rdb |
139,049 | 126,582–151,515 | 0.111 | 2 |
| PING_MBULK | valkey/aof-everysec |
135,323 | 115,607–155,039 | 0.118 | 2 |
| PING_MBULK | valkey/aof-always |
130,711 | 106,383–155,039 | 0.124 | 2 |
| SET | pg_resp/unlogged |
28,928 | 28,531–29,326 | 0.671 | 2 |
| SET | pg_resp/logged-async |
28,674 | 28,653–28,694 | 0.677 | 2 |
| SET | pg_resp/logged |
21,945 | 21,668–22,222 | 0.893 | 2 |
| SET | valkey/none |
140,547 | 130,719–150,376 | 0.105 | 2 |
| SET | valkey/rdb |
145,456 | 144,928–145,985 | 0.102 | 2 |
| SET | valkey/aof-everysec |
120,512 | 113,636–127,389 | 0.140 | 2 |
| SET | valkey/aof-always |
42,646 | 39,526–45,767 | 0.450 | 2 |
Run configuration
- Host:
Linux cursor 6.12.94+ #1 SMP PREEMPT_DYNAMIC Wed Jul 22 16:29:09 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux - Container engine:
podman - Valkey image:
docker.io/valkey/valkey:8.1 - Tests:
ping_mbulk,set,get - Value size:
3bytes - Random keyspace:
10000 - Benchmark client:
unknown
How to read the numbers
- Unlogged / logged-async SET is much slower than Valkey volatile modes because each write goes through Postgres SQL storage.
- Logged vs AOF-always is the fairest “pay for durability” comparison; GET stays read-path bound and closer across modes.
- PING is mostly protocol overhead — useful to separate gateway cost from storage cost.
Choose the mode that matches your failure model, then budget for the SET ratio you see in that pairing.
Running benchmarks yourself
Operators who want to reproduce or tune locally can run the same matrix. This is optional — published results above are the primary reference.
make postgres-up # pg_resp RESP on :6379
make bench # current PG mode vs Valkey (default durable pairing)
make bench-matrix # full durability matrix with repeated medians
| Variable | Role |
|---|---|
BENCH_REQUESTS |
Requests per test |
BENCH_CLIENTS |
Concurrent clients |
BENCH_PIPELINE |
Pipeline depth |
BENCH_MATRIX_REPETITIONS |
Repetitions for matrix medians |
PG_STORAGE_MODE |
PostRESP mode for single benches |
BASELINE_MODE |
Valkey mode for single benches |
PG_STORAGE_MODE=unlogged BASELINE_MODE=none make bench
BENCH_REQUESTS=50000 BENCH_CLIENTS=20 BENCH_PIPELINE=16 make bench