Implementing Rate Limiting with Redis: setnx, ZSet, and Token‑Bucket Techniques
This article explains three Redis‑based rate‑limiting strategies—using SETNX, sorted‑set (ZSet) sliding windows, and a token‑bucket algorithm with List—provides Java code examples for each method, discusses their advantages and drawbacks, and shows how to integrate them into backend services.
When handling high‑concurrency scenarios, rate limiting becomes essential. Redis offers powerful capabilities, and the author demonstrates three practical implementations that can be quickly adopted.
Method 1: SETNX‑based limiting – By leveraging Redis' SETNX command with an expiration time, you can allow only a fixed number of requests within a given interval (e.g., 20 requests per 10 seconds). The approach is simple but cannot slide the window (e.g., from 2‑11 seconds).
Method 2: ZSet (sorted‑set) sliding window – A ZSet stores each request as a unique member (UUID) with the current timestamp as its score. By querying the range of scores within the desired time window, you obtain the request count, achieving a true sliding window. The following Java method shows the implementation:
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 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("访问成功");
}While effective, the ZSet grows over time as entries accumulate.
Method 3: Token‑bucket using List – The token bucket controls request flow by storing tokens in a Redis List. Each request attempts to LEFTPOP a token; if none are available, the request is rejected. Tokens are replenished periodically via a scheduled task:
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());
}This method combines a simple token‑bucket algorithm with Redis' List structure, ensuring each token is unique (generated via UUID) and refreshed at a fixed rate.
In summary, these three Redis‑based rate‑limiting techniques are straightforward to implement and can be integrated into AOP or filter layers to protect APIs. Redis also offers many other features beyond caching and distributed locks, such as GeoHash, BitMap, HyperLogLog, and Bloom filters, which are worth exploring.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.