Implementing Rate Limiting with Redis: setnx, ZSet Sliding Window, and Token‑Bucket Approaches
This article explains three Redis‑based rate‑limiting techniques—using setnx for simple counters, leveraging ZSet for a sliding‑window algorithm, and applying a token‑bucket pattern with List—provides Java code examples for each method, discusses their advantages and drawbacks, and shows how to integrate them into backend services.
Facing increasing high‑concurrency scenarios, rate limiting becomes essential. Redis, with its rich data structures, can be used to implement several effective rate‑limiting strategies.
1. Using Redis SETNX for Simple Counters
By employing the SETNX command together with an expiration time, you can allow only a fixed number of requests within a given time window (e.g., 20 requests in 10 seconds). When the counter reaches the limit, further requests are rejected. This method is straightforward but cannot handle sliding windows (e.g., counting requests from 2‑11 seconds when the original window is 1‑10).
2. Sliding‑Window Rate Limiting with Redis ZSET
The sliding‑window algorithm requires tracking request timestamps. A Redis ZSET can store each request as a member with the current timestamp as its score. By querying the range of scores within the desired interval, you obtain the number of requests in that period.
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("访问成功");
}This implementation achieves a sliding‑window effect, ensuring that at most M requests are processed in any N ‑second interval. The main drawback is that the ZSET size grows over time.
3. Token‑Bucket Rate Limiting with Redis LIST
The token‑bucket algorithm treats each request as a token. Tokens are stored in a Redis list; a request succeeds if it can pop a token from the left side of the list.
public Response limitFlow2(Long id) {
Object result = redisTemplate.opsForList().leftPop("limit_list");
if (result == null) {
return Response.ok("当前令牌桶中无令牌");
}
return Response.ok(articleDescription2);
}A scheduled task periodically replenishes the bucket by pushing new unique tokens (UUIDs) to the right side of the list.
@Scheduled(fixedDelay = 10_000, initialDelay = 0)
public void setIntervalTimeTask() {
redisTemplate.opsForList().rightPush("limit_list", UUID.randomUUID().toString());
}Combining these snippets with AOP or servlet filters enables easy integration of rate limiting into your APIs, protecting the service from overload.
Beyond rate limiting, Redis also supports caching, distributed locks, and advanced data structures such as GeoHash, BitMap, HyperLogLog, and Bloom filters (available from Redis 4.0 via the rebloom module).
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.