Katkat

Implement Sliding-Window Rate Limiter

RobloxSoftware Engineer · Technical Screen

Last updated

This problem tests your ability to implement a thread-safe rate limiter using a sliding window algorithm to ensure a user does not exceed a fixed number of requests within a rolling time frame.

Sliding-Window Rate Limiter

You are tasked with building a RateLimiter class that enforces a rate limit for a specific user. The goal is to allow a maximum of k requests within any rolling window of t milliseconds.

Implement the following interface:

class RateLimiter:
    def __init__(self, k: int, t: int):
        """
        Initializes the rate limiter with capacity k and window size t (in ms).
        """
        pass

    def allow_request(self, user_id: str, timestamp: int) -> bool:
        """
        Returns True if the request at 'timestamp' is allowed, False otherwise.
        Assume timestamps are provided in strictly increasing order.
        """
        pass

Constraints

  • k (capacity) is a positive integer.
  • t (window size) is a positive integer.
  • timestamp is a positive integer.
  • The solution should efficiently evict expired timestamps to save memory.

Examples

Example 1: Capacity k = 2, window t = 1000 ms.

  • allow_request("user1", 100) -> True
  • allow_request("user1", 500) -> True
  • allow_request("user1", 1200) -> True (The request at 100 is evicted because 1200 - 1000 = 200, which is > 100)
  • allow_request("user1", 1300) -> False (Only request at 500 and 1200 remain; at 1300, 500 is still within the window [300, 1300])

Edge Cases

  • Concurrent calls for different user_ids.
  • Requests arriving at the exact boundary of the window.
  • High-frequency requests exceeding k.

Hints

Hint 1

Consider storing a collection of timestamps for each user and removing those that fall outside the current window relative to the new request's timestamp.

Hint 2

A queue-like structure or a deque is ideal for storing timestamps, as they are naturally ordered by time.

Hint 3

Use a dictionary to map each `user_id` to its respective `deque` of timestamps to handle multiple users simultaneously.

Follow-up questions

  • How would you handle the requirement for thread safety if multiple requests from the same user arrive simultaneously?
  • If the number of users grows to millions, how would you optimize memory usage beyond storing all timestamps for every user?
  • How would you adapt this logic to a distributed system where rate limiting needs to be synchronized across multiple application servers?