Rate Limiter using Redis

Rate Limiter using Redis

Rate limiting is a common technique used to control the rate of incoming requests or operations from a client. Redis, an in-memory data structure store, can be used effectively for implementing rate limiting due to its fast response times and support for atomic operations.

There are several approaches you can take to implement rate limiting using Redis. Here's one common method:

  1. Define the rate limit parameters: Decide on the maximum number of requests allowed within a specific time window (e.g., 100 requests per minute).
  2. Use Redis' built-in data structures: Redis provides various data structures that can be utilized for rate limiting. One common approach is to use a Sorted Set or a Hash to track request timestamps and associated keys or user identifiers.
  3. Track requests: Each time a request is received, you need to check whether the client has exceeded the rate limit. Here's how you can do it:

  • If you're using a Sorted Set, add the current timestamp along with a unique identifier for the request (e.g., user ID or IP address) to the set.
  • Remove any expired entries from the Sorted Set to keep it clean.
  • Check the number of elements in the Sorted Set for the specific identifier within the defined time window. If it exceeds the limit, reject the request.

  1. Set an expiration time: To prevent the Sorted Set or Hash from growing indefinitely, you can set an expiration time for the data stored. This ensures that old entries are automatically removed from Redis.
  2. Retrieve rate limit information: You may also want to provide feedback to the client about their rate limit status. You can use Redis commands to fetch the number of remaining requests and the time window's expiration time.

It's important to note that implementing rate limiting solely with Redis may not be sufficient in all scenarios. In distributed systems or high-throughput environments, you may need additional mechanisms, such as a distributed cache or a distributed key-value store, to ensure accurate rate limiting across multiple instances or nodes.

Remember to consider the specific requirements and characteristics of your application when designing and implementing rate limiting using Redis.

Concept in action :


import time
import redis


class RateLimiter:
    def __init__(self, redis_host, redis_port, max_requests, time_window):
        self.redis_client = redis.Redis(host=redis_host, port=redis_port)
        self.max_requests = max_requests
        self.time_window = time_window


    def is_request_allowed(self, identifier):
        current_time = int(time.time())


        # Remove expired entries from the sorted set
        self.redis_client.zremrangebyscore(identifier, 0, current_time - self.time_window)


        # Get the count of requests within the time window
        request_count = self.redis_client.zcard(identifier)


        if request_count >= self.max_requests:
            return False


        # Add current timestamp to the sorted set
        self.redis_client.zadd(identifier, {current_time: current_time})
        
        # Set expiration time for the sorted set
        self.redis_client.expire(identifier, self.time_window)


        return True


# Example usage
redis_host = 'localhost'
redis_port = 6379
max_requests = 100
time_window = 60  # 60 seconds


limiter = RateLimiter(redis_host, redis_port, max_requests, time_window)


# Simulating multiple requests
for i in range(110):
    identifier = 'user123'  # Replace with your identifier (e.g., user ID or IP address)
    if limiter.is_request_allowed(identifier):
        print(f"Request {i+1} allowed")
    else:
        print(f"Request {i+1} rejected")
    time.sleep(1)  # Sleep for 1 second between requests        


I think the order of operations to make it work should be 1 zadd 2 zremrangebyscore 3 zcard 4 check threshold

If you are already trimming the older entries from the SortedSet with zremrangebyscore call, then why do you need to expire the whole SortedSet data structure?

Like
Reply

The logic wouldn't work when there are multiple requests at the same timestamp.

Like
Reply

To view or add a comment, sign in

More articles by Yeshwanth Nagaraj

Others also viewed

Explore content categories