Skip to content

Conversation

@chzhoo
Copy link
Contributor

@chzhoo chzhoo commented Aug 19, 2025

Background

By default, when the number of elements in a zset exceeds 128, the underlying data structure adopts a skiplist. We can reduce memory usage by embedding elements into the skiplist. Change the zskiplistNode memory layout as follows:


Before
                 +-------------+
         +-----> | element-sds |
         |       +-------------+
         |
 +------------------+-------+------------------+---------+-----+---------+
 | element--pointer | score | backward-pointer | level-0 | ... | level-N |
 +------------------+-------+------------------+---------+-----+---------+



After
 +-------+------------------+---------+-----+---------+-------------+
 + score | backward-pointer | level-0 | ... | level-N | element-sds |
 +-------+------------------+---------+-----+---------+-------------+

Benchmark step

I generated the test data using the following lua script && cli command. And check memory usage using the info command.

lua script

local start_idx = tonumber(ARGV[1])
local end_idx = tonumber(ARGV[2])
local elem_count = tonumber(ARGV[3])

for i = start_idx, end_idx do
    local key = "zset:" .. string.format("%012d", i)
    local members = {}

    for j = 0, elem_count - 1 do
        table.insert(members, j)
        table.insert(members, "member:" .. j)
    end

    redis.call("ZADD", key, unpack(members))
end

return "OK: Created " .. (end_idx - start_idx + 1) .. " zsets"

valkey-cli command
valkey-cli EVAL "$(catcreate_zsets.lua)" 0 0 100000 ${ZSET_ELEMENT_NUM}

Benchmark result

number of elements in a zset memory usage before optimization memory usage after optimization change
129 1047MB 943MB -9.9%
256 2010MB 1803MB -10.3%
512 3904MB 3483MB -10.8%

Todo

PTAL. If this change looks acceptable, I will look into implementing some tests in the next round.

@codecov
Copy link

codecov bot commented Aug 19, 2025

Codecov Report

❌ Patch coverage is 98.97959% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 72.24%. Comparing base (f36cc20) to head (e6ce4e9).
⚠️ Report is 45 commits behind head on unstable.

Files with missing lines Patch % Lines
src/module.c 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #2508      +/-   ##
============================================
+ Coverage     72.01%   72.24%   +0.22%     
============================================
  Files           126      126              
  Lines         70448    70683     +235     
============================================
+ Hits          50734    51063     +329     
+ Misses        19714    19620      -94     
Files with missing lines Coverage Δ
src/aof.c 81.10% <100.00%> (-0.09%) ⬇️
src/db.c 93.24% <100.00%> (+3.23%) ⬆️
src/debug.c 53.94% <100.00%> (+0.04%) ⬆️
src/defrag.c 82.30% <100.00%> (-0.12%) ⬇️
src/geo.c 93.04% <100.00%> (ø)
src/object.c 81.94% <100.00%> (-0.05%) ⬇️
src/rdb.c 77.11% <100.00%> (+0.07%) ⬆️
src/server.c 88.44% <100.00%> (-0.02%) ⬇️
src/server.h 100.00% <ø> (ø)
src/sort.c 94.85% <100.00%> (+0.03%) ⬆️
... and 3 more

... and 28 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zuiderkwast zuiderkwast requested a review from ranshid August 19, 2025 21:11
@ranshid
Copy link
Member

ranshid commented Aug 20, 2025

I like the direction of this. I would like, however, to share some of my initial thought on that:
While developing the new HFE, I also looked for a generic way to structure a mapped items in Valkey. For this reason I took the existing hashTypeEntry introduced in 8.1 and made it a generic "entry" so it can potentially be used for sets and sorted sets (once we change it to be able to work without a value). In the initial implementation of the new "entry" type I also included the ability to assign metadata to it in addition to the optional value pointer and expiration time. something "in the lines of" #640 (comment) was supposed to allow linking an entry in skiplists.

Now I like your solution as it is optimal in memory saving. I would suggest to consider extending the entry as I initially did.
The downside of my proposal is that it might cost slightly more memory. For example: the field will have to use a minimal sds8 header for the entry bytes (so potentially 2 bytes overhead) + (lets say) 1 byte for the metadata size = 3 bytes overhead from your suggestion. However this way we might be able to get a more generic and reused code, and potentially also be easier to implement sorted-set field expiration (which TBH, I am not even sure how much is being requested).

@zuiderkwast / @madolson what are you thoughts?

@zuiderkwast
Copy link
Contributor

@ranshid Is the idea to use entry.c to embed the complete skiplist node? It seems like a larger refactoring. If we assume that we will not need sorted-set element expiration any time soon, then I think the simple approach done in this PR is better.

Co-authored-by: Viktor Söderqvist <[email protected]>
Signed-off-by: chzhoo <[email protected]>
@ranshid
Copy link
Member

ranshid commented Aug 20, 2025

@ranshid Is the idea to use entry.c to embed the complete skiplist node? It seems like a larger refactoring. If we assume that we will not need sorted-set element expiration any time soon, then I think the simple approach done in this PR is better.

Yes. that was my point as well, but I wanted to point out this option so that we can take a correct decision. I am fine with going with the suggested solution. Will find the time to review the details.

Signed-off-by: chzhoo <[email protected]>
@hpatro
Copy link
Collaborator

hpatro commented Aug 21, 2025

@vitarb You might be interested in reviewing this.

@chzhoo
Copy link
Contributor Author

chzhoo commented Aug 22, 2025

  • Implementing a generic skiplist could be a major update. It might be better to postpone this until we have more well-defined use cases for it.

  • I tend to favor keeping this PR focused and minimal, as it simplifies code reviews and reduces the risk of introducing new bugs. In fact, during the development of this PR, I also noted two additional potential optimizations:

    1. Changing the function signature of zslInsert from:zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) to: zskiplistNode *zslInsert(zskiplist *zsl, double score, const void* ele, size_t ele_len). This can reduce memory allocation and deallocation in certain scenarios.
    2. Further improving the cache locality of the optimized zskiplistNode layout. The optimized memory layout of zskiplistNode may not be optimal for cache locality, as frequently accessed fields such as score, zslNodeHeight, and element-sds might not reside within the same cache line.

    These optimizations were intentionally excluded from this PR to reduce both review complexity and the risk of introducing new bugs. If the current changes are acceptable, I would be happy to explore these enhancements in follow-up PRs over the coming weeks.

  • Thank you for sharing your insights and your subsequent review feedback. @ranshid

@zuiderkwast
Copy link
Contributor

  • I tend to favor keeping this PR focused and minimal

@chzhoo I agree with this approach. 👍

2. Further improving the cache locality of the optimized zskiplistNode layout. The optimized memory layout of zskiplistNode may not be optimal for cache locality, as frequently accessed fields such as score, zslNodeHeight, and element-sds might not reside within the same cache line.

Regarding this (future optimization idea) I wouldn't worry too much about it, unless you have a smart idea that I haven't though about yet(?). The height of the node is usually low, like 3/4 of the nodes have only one level, 3/4 of the remaining nodes have only two levels, and so forth.

For nodes with only one level, we the score, backward-pointer, forward-pointer and span make up 32 bytes. We have 32 bytes left for the element in this cache line. It means we can fit an element of length 29 (excluding the sds header and nul-terminator). For nodes with two levels, we can fit an element of length 13 bytes. I think it seems acceptable, unless you have another smart idea. :)

@chzhoo
Copy link
Contributor Author

chzhoo commented Aug 22, 2025

Regarding this (future optimization idea) I wouldn't worry too much about it, unless you have a smart idea that I haven't though about yet(?). The height of the node is usually low, like 3/4 of the nodes have only one level, 3/4 of the remaining nodes have only two levels, and so forth.

For nodes with only one level, we the score, backward-pointer, forward-pointer and span make up 32 bytes. We have 32 bytes left for the element in this cache line. It means we can fit an element of length 29 (excluding the sds header and nul-terminator). For nodes with two levels, we can fit an element of length 13 bytes. I think it seems acceptable, unless you have another smart idea. :)

The memory layout of skiplistNode in this PR:

 +-------+------------------+---------+-----+---------+-------------+
 | score | backward-pointer | level-0 | ... | level-N | element-sds |
 +-------+------------------+---------+-----+---------+-------------+
 |
 | 
 `-> zskiplistNode-pointer returned to the user

A memory layout with potential performance improvements,referencing RocksDB's inline-skiplist:

 +---------+-----+---------+-------+------------------+-------------+
 | level-n | ... | level-0 | score | backward-pointer | element-sds |
 +---------+-----+---------+-------+----------+-------+-------------+
                 |
                 | 
                 `-> zskiplistNode-pointer returned to the user

The reason I believe the second layout holds potential for optimization lies in the process of accessing the element-sds:

  • In the second layout, the position of element-sds can be directly calculated using the zskiplistNode-pointer alone.

  • In contrast, the first layout requires first accessing the zslNodeHeight to determine the position of element-sds. Since zslNodeHeight and element-sds may not reside in the same cache line (though the probability is relatively low), the first layout carries a higher risk of cache misses.

  • This approach of directly calculating the element-sds position via pointer arithmetic in the second layout reduces dependency on potentially uncached data, thereby improving memory access efficiency.

The above is merely my hypothesis. I will further investigate and validate this aspect, and look forward to continuing this discussion in a separate PR. @zuiderkwast

Copy link
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have skimmed though this change. I didn't do a very careful review of all the details, but I believe this PR looks great and can soon be ready to be merged.

If this change looks acceptable, I will look into implementing some tests in the next round.

Yes, please go ahead. What tests do you have in mind?

I do believe we have existing tests for sorted sets that will cover this code.

@chzhoo
Copy link
Contributor Author

chzhoo commented Aug 27, 2025

Yes, please go ahead. What tests do you have in mind?

I do believe we have existing tests for sorted sets that will cover this code.

I've looked into the test coverage, and you're correct that existing tests for sorted sets cover the most of the updated code. The one exception is the updated code in module.c, which currently isn't covered by tests. I will add the relevant unit tests for this part.

chzhoo added 2 commits August 28, 2025 13:12
Signed-off-by: chzhoo <[email protected]>
Signed-off-by: chzhoo <[email protected]>
@chzhoo
Copy link
Contributor Author

chzhoo commented Aug 28, 2025

I've looked into the test coverage, and you're correct that existing tests for sorted sets cover the most of the updated code. The one exception is the updated code in module.c, which currently isn't covered by tests. I will add the relevant unit tests for this part.

The unit tests have been submitted, and the code is now in a review-ready state.

zslSetNodeHeight(zn, height);
if (ele) {
char *data = ((char *)(zn + 1)) + height * sizeof(struct zskiplistLevel);
*data++ = sdsHdrSize(ele_sds_type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: why do we need to maintain sds header size? can we just keep all pointers to the sds iteself and from there we can always reach the skiplist data... I think the most reasonable layout is?:

+------------------+--------+------+----------+------+---------------+
+ backward-pointer | level-N | ... | level-0 | score  |   element-sds |
+------------------+--------+------+----------+------+---------------+
                                                      |
                                                      |
                                                      Node ptr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranshid I agree this is probably the more optimal representation, but it requires larger code changes. We'll need to change all the direct accesses to the zskiplistNode structs such as node->level[i]. There are many such accesses in the code. Thus, this can be the refinement to the "future optimization ideas" outlined in #2508 (comment).

For this simple PR, I think one byte for the header size is acceptable. We still get a lot of optimization without a large code change. I'm not even sure we will need the "future optimization" at all. It might not be worth the effort.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranshid I agree this is probably the more optimal representation, but it requires larger code changes. We'll need to change all the direct accesses to the zskiplistNode structs such as node->level[i]. There are many such accesses in the code. Thus, this can be the refinement to the "future optimization ideas" outlined in #2508 (comment).

For this simple PR, I think one byte for the header size is acceptable. We still get a lot of optimization without a large code change. I'm not even sure we will need the "future optimization" at all. It might not be worth the effort.

@zuiderkwast I agree this will require more changes. I also think what I suggested is slightly different than the suggestion in #2508 (comment) as this suggestion also save the extra byte used to calculate the sds header size (which I agree is minor). but if we ARE targeting this for 9.1 I am not sure why we cannot put the extra effort to build this as we think would be best.
Given said that, we can do this in 2 stages even for 9.1. We can first introduce the naïve change and also followup with a second PR to optimize it. I would still think we need to have a performance benchmark results so we can evaluate the potential impact.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think what I suggested is slightly different than the suggestion in #2508

Yes that's right.

if we ARE targeting this for 9.1 I am not sure why we cannot put the extra effort to build this as we think would be best

We can, but it's just a large effort for only one byte. I'm not sure if it's worth it. If you want to review it, fine. I just think first PR is small and achieves most of the benefit.

I would still think we need to have a performance benchmark results so we can evaluate the potential impact.

Sure. I can guess the outcome: No performance impact, except for insertion of very large elements. In this case we need to copy large strings.

I don't know if we care much about very large strings in sorted sets. Do we? For key names and hash fields, we don't. We already embed them. Using large keys names is an anti-pattern.

Copy link
Member

@ranshid ranshid Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, but it's just a large effort for only one byte. I'm not sure if it's worth it. If you want to review it, fine. I just think first PR is small and achieves most of the benefit.

I would still think we need to have a performance benchmark results so we can evaluate the potential impact.

Sure. I can guess the outcome: No performance impact, except for insertion of very large elements. In this case we need to copy large strings.

I don't know if we care much about very large strings in sorted sets. Do we? For key names and hash fields, we don't. We already embed them. Using large keys names is an anti-pattern.

I agree there is no expected impact, but some things (like the fact that the score is drifted away from the sds pointer) might have some relevancy although it might even up with the embedded sds improvement. I just think that we need to take care about presenting potential regressions during development since later it makes the bisecting job much more difficult.

Also in this case there is no "keyname". The zset elements are practically values of something and might actually be large. For example very long URLs... In AWS I know sometimes it is used to store ARNs which can reach 2K long...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given said that, we can do this in 2 stages even for 9.1. We can first introduce the naïve change and also followup with a second PR to optimize it. I would still think we need to have a performance benchmark results so we can evaluate the potential impact.

  • Are you concerned about a significant performance drop in ZADD command? I can run benchmark tests later to check.
  • I'm not very familiar with the PR merging process yet. If this PR is targeting version 9.1, will it take a relatively long time to get merged?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you concerned about a significant performance drop in ZADD command? I can run benchmark tests later to check.

It's one of the concerns yes, for large element sizes such as 2KB. Let's run a benchmark with this setup. It's possible to specify commands explicitly on the valkey-benchmark command line.

Additionally, running some benchmark for various z-commands like zscore and zrange to verify that they don't get slower. @ranshid can you line out what specific benchmarks you would want to see? I think we can do it manually rather than waiting for the automated benchmarking to be in place. I don't like PRs hanging indefinitely.

I'm not very familiar with the PR merging process yet. If this PR is targeting version 9.1, will it take a relatively long time to get merged?

We can merge this PR whenever we feel that it's ready. We don't have a feature freeze for 9.0, because we have already created the 9.0 branch.

@zuiderkwast zuiderkwast moved this to In Progress in Valkey 9.1 Sep 1, 2025
Copy link
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posted a few comments.

It's a bit late to get this into 9.0, but we can get it into 9.1 instead. Added it to the plan.

Regarding the benchmarks, I believe the memory saving is exactly 7 bytes per element, regardless of other factors, right? (remove one pointer and add one byte for sds hdr size). The relative savings then very much depends on the size of the elements then, not very much the number of elements in a sorted set. I can see in your Lua script you used 12 bytes elements in all tests.

chzhoo and others added 3 commits September 1, 2025 23:11
Co-authored-by: Viktor Söderqvist <[email protected]>
Signed-off-by: chzhoo <[email protected]>
Co-authored-by: Viktor Söderqvist <[email protected]>
Signed-off-by: chzhoo <[email protected]>
Co-authored-by: Viktor Söderqvist <[email protected]>
Signed-off-by: chzhoo <[email protected]>
@chzhoo
Copy link
Contributor Author

chzhoo commented Sep 1, 2025

Regarding the benchmarks, I believe the memory saving is exactly 7 bytes per element, regardless of other factors, right?

Yes, you are right.

Copy link
Member

@ranshid ranshid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

Copy link
Member

@ranshid ranshid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some small comments

@github-actions
Copy link

github-actions bot commented Sep 2, 2025

Benchmark ran on this commit: 0d1cc2b

Benchmark Comparison by Command

GET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 968054.19 982318.25 14264.06 +1.47%
latency_avg_ms 0.46 0.45 -0.01 -1.53%
latency_p50_ms 0.44 0.43 -0.01 -1.82%
latency_p95_ms 0.61 0.61 -0.01 -1.30%
latency_p99_ms 0.73 0.72 -0.01 -1.10%

GET | cluster enabled | tls disabled

Metric Baseline PR Diff % Change
rps 836120.44 848896.44 12776.00 +1.53%
latency_avg_ms 0.54 0.53 -0.01 -1.85%
latency_p50_ms 0.54 0.53 -0.01 -1.50%
latency_p95_ms 0.70 0.69 -0.01 -1.14%
latency_p99_ms 0.76 0.75 -0.01 -1.05%

MGET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 313479.62 318877.56 5397.94 +1.72%
latency_avg_ms 1.42 1.39 -0.03 -2.04%
latency_p50_ms 1.42 1.38 -0.03 -2.26%
latency_p95_ms 1.77 1.75 -0.02 -1.35%
latency_p99_ms 1.85 1.82 -0.02 -1.30%

MSET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 216262.97 216450.22 187.25 +0.09%
latency_avg_ms 2.22 2.22 -0.01 -0.27%
latency_p50_ms 2.33 2.32 -0.01 -0.34%
latency_p95_ms 2.56 2.55 -0.01 -0.31%
latency_p99_ms 2.63 2.62 -0.01 -0.30%

SET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 858369.12 827129.88 -31239.24 -3.64%
latency_avg_ms 0.53 0.55 0.02 +4.00%
latency_p50_ms 0.52 0.54 0.02 +4.62%
latency_p95_ms 0.69 0.71 0.02 +3.49%
latency_p99_ms 0.73 0.75 0.02 +2.18%

SET | cluster enabled | tls disabled

Metric Baseline PR Diff % Change
rps 659195.81 667111.44 7915.63 +1.20%
latency_avg_ms 0.70 0.69 -0.01 -1.28%
latency_p50_ms 0.71 0.69 -0.02 -2.25%
latency_p95_ms 0.89 0.88 -0.01 -0.90%
latency_p99_ms 1.14 1.11 -0.02 -2.11%

@ranshid
Copy link
Member

ranshid commented Sep 2, 2025

Benchmark ran on this commit: 0d1cc2b

Benchmark Comparison by Command

GET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 968054.19 982318.25 14264.06 +1.47%
latency_avg_ms 0.46 0.45 -0.01 -1.53%
latency_p50_ms 0.44 0.43 -0.01 -1.82%
latency_p95_ms 0.61 0.61 -0.01 -1.30%
latency_p99_ms 0.73 0.72 -0.01 -1.10%

GET | cluster enabled | tls disabled

Metric Baseline PR Diff % Change
rps 836120.44 848896.44 12776.00 +1.53%
latency_avg_ms 0.54 0.53 -0.01 -1.85%
latency_p50_ms 0.54 0.53 -0.01 -1.50%
latency_p95_ms 0.70 0.69 -0.01 -1.14%
latency_p99_ms 0.76 0.75 -0.01 -1.05%

MGET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 313479.62 318877.56 5397.94 +1.72%
latency_avg_ms 1.42 1.39 -0.03 -2.04%
latency_p50_ms 1.42 1.38 -0.03 -2.26%
latency_p95_ms 1.77 1.75 -0.02 -1.35%
latency_p99_ms 1.85 1.82 -0.02 -1.30%

MSET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 216262.97 216450.22 187.25 +0.09%
latency_avg_ms 2.22 2.22 -0.01 -0.27%
latency_p50_ms 2.33 2.32 -0.01 -0.34%
latency_p95_ms 2.56 2.55 -0.01 -0.31%
latency_p99_ms 2.63 2.62 -0.01 -0.30%

SET | cluster disabled | tls disabled

Metric Baseline PR Diff % Change
rps 858369.12 827129.88 -31239.24 -3.64%
latency_avg_ms 0.53 0.55 0.02 +4.00%
latency_p50_ms 0.52 0.54 0.02 +4.62%
latency_p95_ms 0.69 0.71 0.02 +3.49%
latency_p99_ms 0.73 0.75 0.02 +2.18%

SET | cluster enabled | tls disabled

Metric Baseline PR Diff % Change
rps 659195.81 667111.44 7915.63 +1.20%
latency_avg_ms 0.70 0.69 -0.01 -1.28%
latency_p50_ms 0.71 0.69 -0.02 -2.25%
latency_p95_ms 0.89 0.88 -0.01 -0.90%
latency_p99_ms 1.14 1.11 -0.02 -2.11%

Oh... no zset benchmark yet :(

@madolson
Copy link
Member

madolson commented Sep 3, 2025

@ranshid its easier to add. It's only a few lines and we can re-run the test.

@ranshid
Copy link
Member

ranshid commented Sep 3, 2025

@ranshid its easier to add. It's only a few lines and we can re-run the test.

@madolson depends on how you refer to "few lines"...
Since the current benchmarking framework is built on is built on existing valkey-benchmark testing scenarios it is missing some of the required commands like ZRANGE and ZSCORE. In fact the current benchmark define SPOP and ZPOP as read commands here (which is not true and might impact the test as the original fillup will be cleaned)

So I feel some things needs to be done:

  1. Add ZSCORE and ZRANGE test scenarios to valkey-benchmark. Alternatively we can maybe modify the performance framework to accept a specific command instead of running a test scenario.
  2. Fix the performance-benchmark to not use SPOP and ZPOPMIN as READ commands.
  3. Add the new command scenarios to performance-benchmark
  4. Modify the workflow config to use more data size values + support more commands

I will try to evaluate if I can simply so that or I will open up issues to followup on that

@ranshid
Copy link
Member

ranshid commented Sep 3, 2025

@ranshid its easier to add. It's only a few lines and we can re-run the test.

@madolson depends on how you refer to "few lines"... Since the current benchmarking framework is built on is built on existing valkey-benchmark testing scenarios it is missing some of the required commands like ZRANGE and ZSCORE. In fact the current benchmark define SPOP and ZPOP as read commands here (which is not true and might impact the test as the original fillup will be cleaned)

So I feel some things needs to be done:

  1. Add ZSCORE and ZRANGE test scenarios to valkey-benchmark. Alternatively we can maybe modify the performance framework to accept a specific command instead of running a test scenario.
  2. Fix the performance-benchmark to not use SPOP and ZPOPMIN as READ commands.
  3. Add the new command scenarios to performance-benchmark
  4. Modify the workflow config to use more data size values + support more commands

I will try to evaluate if I can simply so that or I will open up issues to followup on that

@madolson indeed few line changes. take a look at:
#2575 and valkey-io/valkey-perf-benchmark#7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

5 participants