Implement a Leaky Bucket Limiter
SnapchatSoftware Engineer · OnsiteLast updated
This problem tests your ability to implement a thread-safe rate limiter using the Leaky Bucket algorithm, requiring careful management of timestamps and shared state.
Problem Statement
Implement a LeakyBucket class that regulates traffic based on a fixed capacity and a constant leak rate. The bucket holds a maximum of capacity tokens. Tokens are added to the bucket periodically (the 'leak' process), effectively limiting the number of requests allowed within a time window.
API Design
Implement the following methods:
__init__(self, capacity: int, leak_rate_per_second: float): Initializes the bucket.capacityis the maximum number of requests allowed in the burst.leak_rate_per_secondis how many requests can be processed per second.allow_request(self) -> bool: ReturnsTrueif a request can be processed (if a token is available), otherwise returnsFalse.
Requirements
- The implementation must be thread-safe.
- Use
time.time()to track the passage of time. - Ensure the bucket state is updated lazily (i.e., calculate the number of leaked tokens only when a request arrives).
Examples
# Capacity 3, Leak rate 1.0 request per second
bucket = LeakyBucket(3, 1.0)
bucket.allow_request() # Returns True (Current bucket: 2)
bucket.allow_request() # Returns True (Current bucket: 1)
bucket.allow_request() # Returns True (Current bucket: 0)
bucket.allow_request() # Returns False
# Wait 2 seconds
# Bucket now has 2 tokens (1 per second)
bucket.allow_request() # Returns True
Constraints
capacity> 0leak_rate_per_second> 0- Handle high-concurrency environments using locks.
Edge Cases
- Requesting at the exact millisecond a token is generated.
- Multiple threads calling
allow_request()simultaneously. - Very high throughput exceeding the capacity significantly.
Hints
Hint 1
Instead of running a background thread, calculate the number of tokens leaked since the last request based on the elapsed time.
Hint 2
Use a timestamp variable to store when the bucket was last updated and update this timestamp only when `allow_request` is invoked.
Hint 3
Wrap the state updates (timestamp and current token count) inside a mutual exclusion lock to ensure atomicity in a multi-threaded environment.
Follow-up questions
- How would you modify this implementation to support distributed rate limiting across multiple server instances?
- What are the trade-offs between the Leaky Bucket algorithm and the Token Bucket algorithm in terms of traffic shaping?
- If the 'leak rate' changed dynamically based on server load, how would you adjust the logic to prevent race conditions during updates?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.