Bird
Raised Fist0
Rest APIprogramming~5 mins

Per-user vs per-IP limits in Rest API

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction

We use limits to control how many times someone can use an API. This helps keep the system safe and fair for everyone.

To stop one user from sending too many requests and slowing down the service.
To prevent many users from the same place (like a school or office) from overloading the system.
To protect the API from attacks where many requests come from one IP address.
To make sure all users get a fair chance to use the API without being blocked by others.
To track and manage usage for billing or monitoring purposes.
Syntax
Rest API
Limit per user:
  Check user ID or token and count requests.
  Block or slow down if limit exceeded.

Limit per IP:
  Check IP address of the request.
  Count requests from that IP.
  Block or slow down if limit exceeded.

Per-user limits require users to be logged in or identified.

Per-IP limits work even if users are not logged in but can affect many users behind one IP.

Examples
Limit requests by user ID to 1000.
Rest API
if requests_from_user > 1000:
    block_request()
Limit requests by IP address to 5000.
Rest API
if requests_from_ip > 5000:
    block_request()
Use both limits together for better control.
Rest API
if requests_from_user > 1000 or requests_from_ip > 5000:
    block_request()
Sample Program

This program counts requests per user and per IP. It blocks users who send more than 3 requests and blocks IPs with more than 7 requests total.

Rest API
class RateLimiter:
    def __init__(self):
        self.user_counts = {}
        self.ip_counts = {}
        self.user_limit = 3
        self.ip_limit = 7

    def request(self, user_id, ip):
        self.user_counts[user_id] = self.user_counts.get(user_id, 0) + 1
        self.ip_counts[ip] = self.ip_counts.get(ip, 0) + 1

        if self.user_counts[user_id] > self.user_limit:
            return f"User {user_id} blocked: too many requests"
        if self.ip_counts[ip] > self.ip_limit:
            return f"IP {ip} blocked: too many requests"
        return "Request allowed"

limiter = RateLimiter()

# Simulate requests
print(limiter.request('alice', '192.168.1.1'))
print(limiter.request('alice', '192.168.1.1'))
print(limiter.request('alice', '192.168.1.1'))
print(limiter.request('alice', '192.168.1.1'))  # Should block user

print(limiter.request('bob', '192.168.1.1'))
print(limiter.request('carol', '192.168.1.1'))
print(limiter.request('dave', '192.168.1.1'))
print(limiter.request('eve', '192.168.1.1'))  # Should block IP
OutputSuccess
Important Notes

Per-user limits need a way to identify users, like login or API keys.

Per-IP limits can block many users if they share the same IP, like in offices or schools.

Combining both limits gives better protection and fairness.

Summary

Per-user limits control requests based on who is using the API.

Per-IP limits control requests based on where the requests come from.

Using both helps keep the API safe and fair for everyone.

Practice

(1/5)
1. What is the main difference between per-user and per-IP rate limits in REST APIs?
easy
A. Per-user limits block IP addresses; per-IP limits block user accounts.
B. Per-user limits count requests from each IP; per-IP limits count requests from each user.
C. Per-user limits track requests by user identity; per-IP limits track requests by the requester's IP address.
D. Per-user limits apply only to logged-out users; per-IP limits apply only to logged-in users.

Solution

  1. Step 1: Understand per-user limits

    Per-user limits count how many requests each user (identified by login or token) makes.
  2. Step 2: Understand per-IP limits

    Per-IP limits count requests based on the IP address making the request, regardless of user identity.
  3. Final Answer:

    Per-user limits track requests by user identity; per-IP limits track requests by the requester's IP address. -> Option C
  4. Quick Check:

    Per-user = user identity, Per-IP = IP address [OK]
Hint: User limits track users; IP limits track locations [OK]
Common Mistakes:
  • Confusing user identity with IP address
  • Thinking per-IP limits block users
  • Assuming per-user limits apply only to logged-out users
2. Which of the following is the correct way to check a per-user rate limit in pseudocode?
easy
A. if requests_from_user > limit: block_request()
B. if requests_from_ip > limit: block_request()
C. if user_ip == limit: block_request()
D. if user == limit: block_request()

Solution

  1. 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.
  2. Step 2: Verify correct syntax

    The correct syntax is to compare requests_from_user > limit and block if true.
  3. Final Answer:

    if requests_from_user > limit: block_request() -> Option A
  4. Quick Check:

    Check user requests count > limit [OK]
Hint: Per-user means check requests_from_user variable [OK]
Common Mistakes:
  • Using IP variable for per-user limit
  • Comparing user or IP directly to limit
  • Using equality instead of greater than
3. Given this pseudocode snippet for rate limiting:
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?
medium
A. Request allowed
B. User limit reached
C. IP limit reached
D. Error: Key not found

Solution

  1. 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.
  2. Step 2: Determine which print runs

    Since the first condition is true, it prints "User limit reached" and skips the rest.
  3. Final Answer:

    User limit reached -> Option B
  4. Quick Check:

    5 >= 5 triggers user limit [OK]
Hint: Check user count first; equal means limit reached [OK]
Common Mistakes:
  • Thinking IP limit triggers first
  • Ignoring >= condition
  • Assuming else runs when equal
4. This code snippet is intended to enforce per-IP rate limits but has a bug:
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?
medium
A. Bug: Uses > instead of >=; fix by changing to >=.
B. Bug: ip variable is wrong type; fix by converting to string.
C. Bug: requests_per_ip key missing; fix by adding default value.
D. Bug: prints wrong message; fix by swapping print statements.

Solution

  1. 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.
  2. Step 2: Fix condition to include equal case

    Change > to >= so requests equal to ip_limit also get blocked.
  3. Final Answer:

    Bug: Uses > instead of >=; fix by changing to >=. -> Option A
  4. Quick Check:

    Use >= to block at limit [OK]
Hint: Use >= to block requests at limit, not just above [OK]
Common Mistakes:
  • Ignoring equal case in condition
  • Assuming IP variable type is wrong
  • Thinking missing keys cause this bug
5. You want to implement a rate limiter that blocks requests if either the user or the IP address exceeds their limits. Which pseudocode correctly enforces this combined rule?
hard
A. if requests_per_user[user] > user_limit and requests_per_ip[ip] > ip_limit: block_request()
B. if requests_per_user[user] == user_limit and requests_per_ip[ip] == ip_limit: block_request()
C. if requests_per_user[user] < user_limit or requests_per_ip[ip] < ip_limit: block_request()
D. if requests_per_user[user] > user_limit or requests_per_ip[ip] > ip_limit: block_request()

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    if requests_per_user[user] > user_limit or requests_per_ip[ip] > ip_limit: block_request() -> Option D
  4. Quick Check:

    Block if user OR IP exceeds limit [OK]
Hint: Use OR to block if either user or IP exceeds limit [OK]
Common Mistakes:
  • Using AND instead of OR
  • Using < instead of >
  • Checking equality only