Master Redis Rate Limiting: SetNX, ZSet Sliding Window, and Token Bucket

This article explains three practical Redis-based rate‑limiting techniques—using SETNX for simple counters, ZSET for a sliding‑window algorithm, and a token‑bucket implementation with List—complete with Java code examples and discussion of their advantages and drawbacks.

Programmer DD
Programmer DD
Programmer DD
Master Redis Rate Limiting: SetNX, ZSet Sliding Window, and Token Bucket

First Method: Using Redis SETNX

Redis' distributed lock relies on the SETNX command combined with an expiration time. By setting a key with SETNX and an expire of, for example, 10 seconds, you can limit the number of requests within that interval; when the count reaches the limit, further requests are blocked. This approach is simple but cannot handle sliding windows (e.g., counting requests from 2‑11 seconds when the fixed window is 1‑10 seconds).

Second Method: Using Redis ZSET

The sliding‑window problem can be solved with Redis' sorted set (ZSET). Each request is added as a member with a unique value (e.g., a UUID) and a score equal to the current timestamp. By querying the range of scores within the desired time interval, you can count how many requests occurred. The following code demonstrates this approach:

public Response limitFlow() {
    Long currentTime = new Date().getTime();
    System.out.println(currentTime);
    if (redisTemplate.hasKey("limit")) {
        Integer count = redisTemplate.opsForZSet()
            .rangeByScore("limit", currentTime - intervalTime, currentTime)
            .size(); // intervalTime is the rate‑limit period
        System.out.println(count);
        if (count != null && count > 5) {
            return Response.ok("每分钟最多只能访问5次");
        }
    }
    redisTemplate.opsForZSet().add("limit", UUID.randomUUID().toString(), currentTime);
    return Response.ok("访问成功");
}

This implementation provides a sliding‑window effect, ensuring at most M requests per N seconds, but the ZSET size grows over time.

Third Method: Token Bucket with Redis List

The token‑bucket algorithm controls flow by maintaining a pool of tokens. Each request attempts to pop a token from a Redis list; if a token is obtained, the request proceeds, otherwise it is rejected. Tokens are replenished periodically using a scheduled task that pushes unique identifiers (UUIDs) onto the list.

public Response limitFlow2(Long id) {
    Object result = redisTemplate.opsForList().leftPop("limit_list");
    if (result == null) {
        return Response.ok("当前令牌桶中无令牌");
    }
    return Response.ok(articleDescription2);
}
@Scheduled(fixedDelay = 10_000, initialDelay = 0)
public void setIntervalTimeTask() {
    redisTemplate.opsForList().rightPush("limit_list", UUID.randomUUID().toString());
}

By integrating any of these snippets into an AOP interceptor or servlet filter, you can protect your APIs from excessive traffic.

Beyond rate limiting, Redis offers many other data structures and features such as GeoHash, BitMap, HyperLogLog, and Bloom filters (available from Redis 4.0 onward), which are worth exploring for advanced use cases.

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.

JavaBackend DevelopmentredisSpring Bootrate limitingSliding WindowToken Bucket
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.