Per-user vs per-IP limits in Rest API - Performance Comparison
Start learning this pattern below
Jump into concepts and practice - no test required
When setting limits on API requests, it's important to understand how the system handles these limits.
We want to see how the number of checks grows as more users or IPs make requests.
Analyze the time complexity of the following code snippet.
// Check if user has exceeded request limit
if (userRequests[userId] > userLimit) {
rejectRequest();
}
// Check if IP has exceeded request limit
if (ipRequests[ipAddress] > ipLimit) {
rejectRequest();
}
// Process request if limits not exceeded
processRequest();
This code checks request counts per user and per IP address before allowing the request.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Checking request counts in user and IP maps.
- How many times: Once per incoming request.
Each request triggers two quick lookups: one for the user and one for the IP.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 requests | 20 lookups (2 per request) |
| 100 requests | 200 lookups |
| 1000 requests | 2000 lookups |
Pattern observation: Operations grow directly with the number of requests.
Time Complexity: O(n)
This means the time to check limits grows linearly with the number of requests.
[X] Wrong: "Checking per-user and per-IP limits means the time grows with the number of users or IPs."
[OK] Correct: Each request only checks its own user and IP, so time depends on requests, not total users or IPs.
Understanding how per-user and per-IP checks scale helps you design fair and efficient APIs.
What if we added a nested loop to check all users' request counts on each request? How would the time complexity change?
Practice
per-user and per-IP rate limits in REST APIs?Solution
Step 1: Understand per-user limits
Per-user limits count how many requests each user (identified by login or token) makes.Step 2: Understand per-IP limits
Per-IP limits count requests based on the IP address making the request, regardless of user identity.Final Answer:
Per-user limits track requests by user identity; per-IP limits track requests by the requester's IP address. -> Option CQuick Check:
Per-user = user identity, Per-IP = IP address [OK]
- Confusing user identity with IP address
- Thinking per-IP limits block users
- Assuming per-user limits apply only to logged-out users
Solution
Step 1: Identify per-user check
Per-user limits check how many requests a user has made, so the condition should compare requests_from_user to the limit.Step 2: Verify correct syntax
The correct syntax is to compare requests_from_user > limit and block if true.Final Answer:
if requests_from_user > limit: block_request() -> Option AQuick Check:
Check user requests count > limit [OK]
- Using IP variable for per-user limit
- Comparing user or IP directly to limit
- Using equality instead of greater than
requests_per_user = {"alice": 5, "bob": 3}
requests_per_ip = {"192.168.1.1": 10, "10.0.0.2": 2}
user = "alice"
ip = "192.168.1.1"
user_limit = 5
ip_limit = 10
if requests_per_user[user] >= user_limit:
print("User limit reached")
elif requests_per_ip[ip] >= ip_limit:
print("IP limit reached")
else:
print("Request allowed")What will be printed?
Solution
Step 1: Check user request count
requests_per_user["alice"] is 5, which is equal to user_limit (5), so the first if condition is true.Step 2: Determine which print runs
Since the first condition is true, it prints "User limit reached" and skips the rest.Final Answer:
User limit reached -> Option BQuick Check:
5 >= 5 triggers user limit [OK]
- Thinking IP limit triggers first
- Ignoring >= condition
- Assuming else runs when equal
requests_per_ip = {"1.2.3.4": 8}
ip_limit = 10
ip = "1.2.3.4"
if requests_per_ip[ip] > ip_limit:
print("Limit exceeded")
else:
print("Allowed")What is the bug and how to fix it?
Solution
Step 1: Analyze condition logic
The code blocks requests only if requests_per_ip[ip] > ip_limit, so if requests equal ip_limit, it allows the request.Step 2: Fix condition to include equal case
Change > to >= so requests equal to ip_limit also get blocked.Final Answer:
Bug: Uses > instead of >=; fix by changing to >=. -> Option AQuick Check:
Use >= to block at limit [OK]
- Ignoring equal case in condition
- Assuming IP variable type is wrong
- Thinking missing keys cause this bug
Solution
Step 1: Understand combined blocking logic
The request should be blocked if either the user or the IP exceeds their limit, so the condition must use OR.Step 2: Check condition correctness
if requests_per_user[user] > user_limit or requests_per_ip[ip] > ip_limit: block_request() uses OR with > comparisons, correctly blocking if user or IP exceeds limits.Final Answer:
if requests_per_user[user] > user_limit or requests_per_ip[ip] > ip_limit: block_request() -> Option DQuick Check:
Block if user OR IP exceeds limit [OK]
- Using AND instead of OR
- Using < instead of >
- Checking equality only
