#15288·Redis

Possible ZINCRBY performance regression after 391e345

Author: GallopmCreated Jun 1, 2026Updated Sep 17, 2026
Labelsstate-cannot-replicate

I observed a small but reproducible ZINCRBY performance regression after commit 391e345 ("Optimize hash and zset with lpBatchAppend").

The regression was measured with redis-benchmark, comparing the commit against its parent 9a9aa92.

Benchmark

Command under test:

bash
redis-benchmark -n 1000000 -P 10 --csv ZINCRBY key_SortSet:3478 10 1

Each version was tested for 20 rounds. The database was restarted/reset between runs.

Results

Metric Parent 9a9aa921 Commit 391e3452 Change p-value
RPS 253063.65 245026.82 -3.18% 0.000000030
avg latency ms 1.91225 1.98140 +3.62% 0.000000001
p50 latency ms 1.95580 2.05940 +5.30% < 0.000000001
p95 latency ms 2.82180 2.92540 +3.67% 0.006895560
p99 latency ms 3.22020 3.30140 +2.52% 0.306835840

The p99 change was not statistically significant in this run, but RPS, average latency, p50, and p95 were.

This workload repeatedly increments the same sorted-set member. For a small/listpack-encoded zset, after the first request this mainly exercises the existing-member update path in zsetAdd():

  1. find the member,
  2. delete the old (member, score) pair,
  3. reinsert it with the new score.

Commit 391e3452 changed zzlInsertAt() to use lpBatchAppend() / lpBatchInsert() instead of two direct lpAppend() / lpInsert*() calls. That appears beneficial for some ZADD insertion cases, but this ZINCRBY existing-member path seems to regress slightly.

Could you please check whether the batched listpack insertion change has extra overhead for small zset/listpack updates?