Token bucket algorithm in Rest API - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
We want to understand how the time it takes to check and update tokens grows as requests come in.
How does the algorithm handle more requests over time?
Analyze the time complexity of the following code snippet.
def allow_request(bucket, tokens_needed=1):
now = current_time()
elapsed = now - bucket['last_checked']
bucket['tokens'] = min(bucket['capacity'], bucket['tokens'] + elapsed * bucket['rate'])
bucket['last_checked'] = now
if bucket['tokens'] >= tokens_needed:
bucket['tokens'] -= tokens_needed
return True
return False
This code checks if enough tokens are available to allow a request and updates the token count based on elapsed time.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Simple arithmetic and comparisons done once per request.
- How many times: Once each time a request is checked.
The work done for each request stays about the same no matter how many requests come in.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 simple checks and updates |
| 100 | 100 simple checks and updates |
| 1000 | 1000 simple checks and updates |
Pattern observation: The time grows linearly with the number of requests, but each request takes a fixed small amount of work.
Time Complexity: O(1)
This means each request is handled in constant time, no matter how many requests happen.
[X] Wrong: "The token bucket algorithm must loop over all tokens or requests, so it takes longer as requests increase."
[OK] Correct: The algorithm only updates counts using simple math each time a request comes in, without looping over past requests or tokens.
Understanding this helps you explain how rate limiting works efficiently in real systems, showing you can reason about performance in practical code.
"What if we changed the algorithm to store each token as an individual object and check them one by one? How would the time complexity change?"
Practice
What is the main purpose of the token bucket algorithm in REST APIs?
Solution
Step 1: Understand the token bucket algorithm concept
The token bucket algorithm limits how many requests can be processed by controlling tokens that refill over time.Step 2: Identify the purpose in REST APIs
It helps prevent too many requests at once, protecting the server from overload.Final Answer:
To control the rate of incoming requests by using tokens -> Option CQuick Check:
Token bucket controls request rate = C [OK]
- Confusing token bucket with data storage
- Thinking it encrypts data
- Assuming it manages database connections
Which of the following is the correct way to represent a token bucket refill rate in pseudocode?
1. refill_rate = tokens_per_second 2. refill_rate = seconds_per_token 3. refill_rate = max_tokens * time 4. refill_rate = tokens / max_tokens
Solution
Step 1: Understand refill rate meaning
The refill rate is how many tokens are added per second to the bucket.Step 2: Match with options
refill_rate = tokens_per_second correctly shows tokens added per second, which is the refill rate.Final Answer:
refill_rate = tokens_per_second -> Option BQuick Check:
Refill rate = tokens per second [OK]
- Confusing refill rate with time per token
- Multiplying max tokens by time incorrectly
- Using ratios instead of rates
Given a token bucket with max_tokens = 5, refill_rate = 1 token/second, and an empty bucket at time 0, what is the number of tokens available at time 3 seconds?
Solution
Step 1: Calculate tokens refilled after 3 seconds
Since refill rate is 1 token per second, after 3 seconds, 3 tokens are added.Step 2: Check max tokens limit
The bucket max is 5 tokens, so 3 tokens fit without exceeding the max.Final Answer:
3 tokens -> Option AQuick Check:
3 seconds * 1 token/sec = 3 tokens [OK]
- Assuming bucket fills instantly to max
- Ignoring max token limit
- Using refill rate incorrectly
Consider this pseudocode snippet for token bucket check:if tokens <= 0:
reject_request()
else:
tokens -= 1
allow_request()
What is the bug in this logic?
Solution
Step 1: Recall proper token bucket logic
To consume 1 token, check if tokens >= 1 before decrementing (equivalent to reject if tokens < 1).Step 2: Identify the bug
The code rejects only if tokens <= 0. For fractional tokens (common in real implementations), if 0 < tokens < 1, it allows the request, decrementing to negative, which is incorrect.Final Answer:
It should check if tokens < 1, not <= 0 -> Option DQuick Check:
Reject if tokens < 1 [OK]
- Using <= 0 instead of < 1 causes off-by-one errors
- Increasing tokens on request instead of decreasing
- Rejecting requests when tokens are available
You want to implement a token bucket that allows bursts of up to 10 requests and refills tokens at 2 tokens per second. If a client sends 15 requests instantly after being idle for 3 seconds, how many requests will be allowed immediately?
Solution
Step 1: Calculate tokens available after 3 seconds idle
Refill rate is 2 tokens/second, so after 3 seconds: 2 * 3 = 6 tokens. Max tokens allowed is 10, so bucket fills to 6 tokens.Step 2: Consider burst capacity
Since the bucket max is 10, if it was full before idle, it would have 10 tokens. But starting empty, after 3 seconds it has 6 tokens.Step 3: Determine allowed requests
The client sends 15 requests instantly, but only 6 tokens are available, so only 6 requests allowed immediately.Final Answer:
6 requests -> Option AQuick Check:
3 sec * 2 tokens/sec = 6 tokens available [OK]
- Assuming bucket always full at max tokens
- Allowing more requests than tokens available
- Ignoring refill rate and idle time
