Master Sliding‑Window Rate Limiting with Redis Sorted Sets

This article explains how to implement a precise sliding‑window rate‑limiting algorithm using Redis Sorted Sets, detailing the problem scenario, the algorithm steps, Lua script implementation, Java integration, and practical extensions for high‑performance backend services.

Lin is Dream
Lin is Dream
Lin is Dream
Master Sliding‑Window Rate Limiting with Redis Sorted Sets

Redis series article: implementing a sliding‑window rate‑limiting algorithm based on Redis Sorted Sets.

Scenario: a SMS verification code API or a user behavior logging endpoint is overwhelmed by thousands of requests, causing cost spikes and system crashes. The goal is a rate‑limiting method that can accurately count accesses within the past N seconds, works with Redis’s distributed nature, and responds in seconds.

Answer: Use a sliding‑window algorithm implemented with Redis Sorted Set.

The sliding‑window algorithm tracks events within a fixed time window, where the window size represents the time span and the number of keys in the set represents the frequency of events.

Specific Steps

1. Remove all values older than the current window period.

2. Count the total number of values (each value is a unique ID) in the current window.

3. If the count exceeds the allowed limit, trigger rate limiting; otherwise, add a new value with an expiration time.

4. Use ZADD to add the value (key = event identifier, score = timestamp, value = unique ID).

Rate‑Limiting Algorithm

The core idea is to limit the number of uses within a unit of time. By using Redis Sorted Set, the key (MD5 of the deduplicated content) represents an event, the score (timestamp) defines the window, and the set members count as the allowed permits. When the set reaches the threshold, further requests are blocked. The key’s TTL equals the window size, so it expires automatically when no new requests arrive.

Implementation

Lua script for atomic operations:

--KEYS[1]: limit key (deduplicated content hash)
--ARGV[1]: window size (ms)
--ARGV[2]: current timestamp (score)
--ARGV[3]: threshold (max permits)
--ARGV[4]: unique value (ID)
-- return 0 for success, 1 for limit exceeded
redis.call('zremrangeByScore', KEYS[1], 0, ARGV[2]-ARGV[1])
if (redis.call('zcard', KEYS[1]) < tonumber(ARGV[3])) then
  redis.call('zadd', KEYS[1], ARGV[2], ARGV[4])
  redis.call('expire', KEYS[1], ARGV[1]/1000)
  return 0
else
  return 1
end

Java method integrating the script with Redisson:

public boolean tryAccess(String key, int permits, long time, long timeout, TimeUnit unit) {
    if (permits <= 0) return false;
    if (key.length() > Su4jConstants.KEY_MAX_LEN) {
        key = DigestUtil.md5Hex(key);
    }
    key = Su4jConstants.RATELIMIT_PREFIX + key;
    List<Object> keys = Collections.singletonList(key);
    String score = String.valueOf(System.currentTimeMillis());
    String scoreValue = IdUtil.getSnowflakeNextIdStr();
    String expireTime = String.valueOf(time * 1000);
    Object[] args = new Object[]{expireTime, score, permits, scoreValue};
    boolean result = redissonClient.getScript(StringCodec.INSTANCE)
        .eval(RScript.Mode.READ_WRITE, LUA_SCRIPT, RScript.ReturnType.BOOLEAN, keys, args);
    return result;
}

Extensions: the same Sorted Set technique can be applied to ranking systems, where each key represents a business entity (e.g., user points or product sales) and values are unique IDs with scores indicating the ranking metric. Regular cleanup of old entries prevents overload.

Conclusion: Using Redis Sorted Set for sliding‑window rate limiting provides precise time‑based counting, natural ordering, range queries, and automatic expiration, making it an optimal solution for high‑traffic backend services.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaRedisrate limitingLuaSliding WindowSorted Set
Lin is Dream
Written by

Lin is Dream

Sharing Java developer knowledge, practical articles, and continuous insights into computer engineering.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.