Skip to content

Commit 85a3492

Browse files
Updated the memtier_benchmark-playbook-session-storage benchmark to match https://github.com/upstash/examples/tree/main/examples/ratelimit-with-redis
1 parent f6c05d9 commit 85a3492

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

redis_benchmarks_specification/test-suites/memtier_benchmark-playbook-session-storage.yml

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,27 @@ description: |
66
and rate limiting. It includes realistic key sizes and command mixes representative
77
of production traffic (e.g., 400–600B session hashes, ZSETs for analytics, and SETs for tracking).
88
9-
Rate limiting is modeled using Redis counters with expiration and readback: each user has a
10-
dedicated rate-limit key in the form of `ratelimit:user-<id>:/api/resource`, which is:
11-
- incremented (`INCR`) to track API usage,
12-
- assigned a TTL (`EXPIRE`) to define the 60-second rate window,
13-
- and read (`GET`) to simulate application-side decision-making (e.g., to check if a user is over quota).
14-
This models realistic per-user rate-limiting behavior for a single endpoint.
9+
Rate limiting is modeled using an atomic Lua script, inspired by the Upstash Redis example:
10+
https://github.com/upstash/examples/tree/main/examples/ratelimit-with-redis
11+
12+
Each user has a dedicated key in the form of `ratelimit:user-<id>:/api/resource`, which is
13+
used to track usage under a fixed window. The logic is evaluated atomically with the following script:
14+
15+
local key = KEYS[1]
16+
local limit = 100
17+
local window = 60
18+
local current = redis.call("INCR", key)
19+
if current == 1 then
20+
redis.call("EXPIRE", key, window)
21+
end
22+
if current > limit then
23+
return 0
24+
else
25+
return 1
26+
end
27+
28+
This ensures that rate enforcement and usage tracking are done without race conditions, and
29+
mirrors a real-world API quota model.
1530
1631
The workload emphasizes read-heavy patterns to reflect common SaaS access behavior. The overall
1732
**read:write ratio is approximately 85:15**, with read operations covering session access, user-session
@@ -22,7 +37,7 @@ description: |
2237
- Session CRUD (HGETALL, HSET): ~55%
2338
- User session tracking (SMEMBERS, SADD): ~21%
2439
- Organization analytics (ZRANGE, ZADD): ~12%
25-
- Rate limiting (INCR, EXPIRE, GET): ~12%
40+
- Rate limiting (EVAL-based quota check): ~12%
2641
2742
exporter:
2843
redistimeseries:
@@ -37,9 +52,7 @@ exporter:
3752
- $."BEST RUN RESULTS".Sadds."Ops/sec"
3853
- $."BEST RUN RESULTS".Zranges."Ops/sec"
3954
- $."BEST RUN RESULTS".Zadds."Ops/sec"
40-
- $."BEST RUN RESULTS".Incrs."Ops/sec"
41-
- $."BEST RUN RESULTS".Gets."Ops/sec"
42-
- $."BEST RUN RESULTS".Expires."Ops/sec"
55+
- $."BEST RUN RESULTS".Evals."Ops/sec"
4356
- $."BEST RUN RESULTS".Totals."Ops/sec"
4457
- $."BEST RUN RESULTS".Totals."Latency"
4558
- $."BEST RUN RESULTS".Totals."Misses/sec"
@@ -51,9 +64,7 @@ exporter:
5164
- $."ALL STATS".Sadds."Ops/sec"
5265
- $."ALL STATS".Zranges."Ops/sec"
5366
- $."ALL STATS".Zadds."Ops/sec"
54-
- $."ALL STATS".Incrs."Ops/sec"
55-
- $."ALL STATS".Gets."Ops/sec"
56-
- $."ALL STATS".Expires."Ops/sec"
67+
- $."ALL STATS".Evals."Ops/sec"
5768
- $."ALL STATS".Totals."Ops/sec"
5869
- $."ALL STATS".Totals."Latency"
5970
- $."ALL STATS".Totals."Misses/sec"
@@ -63,9 +74,7 @@ exporter:
6374
- $."ALL STATS".Sadds."Percentile Latencies"."p50.00"
6475
- $."ALL STATS".Zranges."Percentile Latencies"."p50.00"
6576
- $."ALL STATS".Zadds."Percentile Latencies"."p50.00"
66-
- $."ALL STATS".Incrs."Percentile Latencies"."p50.00"
67-
- $."ALL STATS".Gets."Percentile Latencies"."p50.00"
68-
- $."ALL STATS".Expires."Percentile Latencies"."p50.00"
77+
- $."ALL STATS".Evals."Percentile Latencies"."p50.00"
6978
- $."ALL STATS".Totals."Percentile Latencies"."p50.00"
7079
- $."ALL STATS".Totals."Percentile Latencies"."p99.00"
7180

@@ -182,15 +191,9 @@ clientconfig:
182191
--command="ZADD org:__key__:sessions 1 user-__key__:session-__key__"
183192
--command-key-pattern=R
184193
--command-ratio=2
185-
--command="INCR ratelimit:user-__key__:/api/resource"
186-
--command-key-pattern=R
187-
--command-ratio=4
188-
--command="EXPIRE ratelimit:user-__key__:/api/resource 60"
189-
--command-key-pattern=R
190-
--command-ratio=1
191-
--command="GET ratelimit:user-__key__:/api/resource"
194+
--command='EVAL "local key=KEYS[1];local limit=10;local window=60;local current=redis.call(\"INCR\",key);if current==1 then redis.call(\"EXPIRE\",key,window) end;if current>limit then return 0 else return 1 end" 1 ratelimit:user-__key__:/api/resource'
192195
--command-key-pattern=R
193-
--command-ratio=7
196+
--command-ratio=12
194197
--hide-histogram
195198
resources:
196199
requests:

0 commit comments

Comments
 (0)