Bird
Raised Fist0
FastAPIframework~20 mins

Rate limiting in FastAPI - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Rate Limiting Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when the rate limit is exceeded in this FastAPI endpoint?

Consider this FastAPI endpoint using a simple rate limiter that allows 3 requests per minute per client IP.

from fastapi import FastAPI, Request, HTTPException
from time import time

app = FastAPI()

request_times = {}

@app.get("/data")
async def get_data(request: Request):
    ip = request.client.host
    now = time()
    window = 60
    limit = 3
    times = request_times.get(ip, [])
    times = [t for t in times if now - t < window]
    if len(times) >= limit:
        raise HTTPException(status_code=429, detail="Too many requests")
    times.append(now)
    request_times[ip] = times
    return {"message": "Success"}

What will the client receive on the 4th request within one minute?

FastAPI
from fastapi import FastAPI, Request, HTTPException
from time import time

app = FastAPI()

request_times = {}

@app.get("/data")
async def get_data(request: Request):
    ip = request.client.host
    now = time()
    window = 60
    limit = 3
    times = request_times.get(ip, [])
    times = [t for t in times if now - t < window]
    if len(times) >= limit:
        raise HTTPException(status_code=429, detail="Too many requests")
    times.append(now)
    request_times[ip] = times
    return {"message": "Success"}
AThe client receives a JSON response with {"message": "Success"} on all requests.
BThe client receives an HTTP 429 error with detail "Too many requests" on the 4th request within one minute.
CThe client receives an HTTP 500 Internal Server Error on the 4th request.
DThe client receives an HTTP 404 Not Found error on the 4th request.
Attempts:
2 left
💡 Hint

Think about what happens when the number of requests exceeds the limit in the code.

📝 Syntax
intermediate
2:00remaining
Identify the syntax error in this FastAPI rate limiting snippet

Which option correctly fixes the syntax error in this code snippet?

from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.get("/limit")
async def limit(request: Request):
    ip = request.client.host
    if ip not in request_times
        request_times[ip] = []
    return {"status": "ok"}
FastAPI
from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.get("/limit")
async def limit(request: Request):
    ip = request.client.host
    if ip not in request_times
        request_times[ip] = []
    return {"status": "ok"}
AIndent the return statement inside the if block.
BReplace 'not in' with 'notin' in the if statement.
CAdd a colon at the end of the if statement line: if ip not in request_times:
DChange 'request_times' to 'request_times()' in the if statement.
Attempts:
2 left
💡 Hint

Python requires a colon at the end of if statements.

❓ state_output
advanced
2:00remaining
What is the value of request_times after 3 requests from the same IP within 30 seconds?

Given this code snippet:

from fastapi import FastAPI, Request
from time import time

app = FastAPI()
request_times = {}

@app.get("/check")
async def check(request: Request):
    ip = request.client.host
    now = time()
    window = 60
    times = request_times.get(ip, [])
    times = [t for t in times if now - t < window]
    times.append(now)
    request_times[ip] = times
    return {"count": len(times)}

If the same client IP makes 3 requests within 30 seconds, what will be the value of request_times[ip] after the third request?

FastAPI
from fastapi import FastAPI, Request
from time import time

app = FastAPI()
request_times = {}

@app.get("/check")
async def check(request: Request):
    ip = request.client.host
    now = time()
    window = 60
    times = request_times.get(ip, [])
    times = [t for t in times if now - t < window]
    times.append(now)
    request_times[ip] = times
    return {"count": len(times)}
AA list of 4 timestamps including an extra one from before.
BA list of 1 timestamp, the last request time only.
CAn empty list because old timestamps are removed.
DA list of 3 timestamps, each less than 60 seconds old.
Attempts:
2 left
💡 Hint

Consider how the code filters timestamps and adds the current time.

🔧 Debug
advanced
2:00remaining
Why does this FastAPI rate limiter not reset counts after 1 minute?

Consider this code snippet:

from fastapi import FastAPI, Request, HTTPException
from time import time

app = FastAPI()
request_counts = {}

@app.get("/limit")
async def limit(request: Request):
    ip = request.client.host
    count, start = request_counts.get(ip, (0, time()))
    if time() - start > 60:
        count = 0
        start = time()
    count += 1
    if count > 5:
        raise HTTPException(status_code=429, detail="Too many requests")
    request_counts[ip] = (count, start)
    return {"count": count}

Why might the count never reset after 1 minute?

FastAPI
from fastapi import FastAPI, Request, HTTPException
from time import time

app = FastAPI()
request_counts = {}

@app.get("/limit")
async def limit(request: Request):
    ip = request.client.host
    count, start = request_counts.get(ip, (0, time()))
    if time() - start > 60:
        count = 0
        start = time()
    count += 1
    if count > 5:
        raise HTTPException(status_code=429, detail="Too many requests")
    request_counts[ip] = (count, start)
    return {"count": count}
ABecause the start time is reset inside the if block but the dictionary is updated after incrementing count, causing inconsistent timing.
BBecause the count variable is never incremented.
CBecause the dictionary request_counts is never updated.
DBecause the time() function returns a constant value.
Attempts:
2 left
💡 Hint

Look at when the start time is updated and when the dictionary is updated.

🧠 Conceptual
expert
3:00remaining
Which approach best ensures accurate distributed rate limiting in FastAPI?

You want to implement rate limiting in a FastAPI app deployed on multiple servers behind a load balancer. Which approach below best ensures accurate rate limiting across all servers?

AUse a shared external store like Redis to track request counts and timestamps centrally.
BUse an in-memory dictionary on each server to track request counts per IP separately.
CUse client-side cookies to store request counts and enforce limits on the client.
DRely on the load balancer to block requests after a fixed number per server.
Attempts:
2 left
💡 Hint

Think about how to share state across multiple servers.

Practice

(1/5)
1.

What is the main purpose of rate limiting in a FastAPI application?

easy
A. To speed up database queries
B. To control how often users can call API endpoints
C. To add more routes automatically
D. To change the API response format

Solution

  1. Step 1: Understand rate limiting concept

    Rate limiting restricts the number of requests a user can make in a time period.
  2. Step 2: Identify the purpose in FastAPI

    It protects the app from overload and abuse by controlling request frequency.
  3. Final Answer:

    To control how often users can call API endpoints -> Option B
  4. Quick Check:

    Rate limiting = Control request frequency [OK]
Hint: Rate limiting means controlling request frequency [OK]
Common Mistakes:
  • Thinking it speeds up queries
  • Confusing with routing features
  • Assuming it changes response format
2.

Which of the following is the correct way to import a rate limiter middleware in FastAPI?

from fastapi import FastAPI
from _____ import RateLimiterMiddleware

app = FastAPI()
app.add_middleware(RateLimiterMiddleware, max_requests=5, window_seconds=60)
easy
A. fastapi_utils
B. fastapi.middleware
C. fastapi_rate_limit
D. fastapi_limiter

Solution

  1. Step 1: Recall FastAPI rate limiting libraries

    FastAPI commonly uses the external package 'fastapi_limiter' for rate limiting middleware.
  2. Step 2: Match import statement

    The correct import is from 'fastapi_limiter' to get RateLimiterMiddleware.
  3. Final Answer:

    fastapi_limiter -> Option D
  4. Quick Check:

    RateLimiterMiddleware import = fastapi_limiter [OK]
Hint: Rate limiter middleware comes from fastapi_limiter package [OK]
Common Mistakes:
  • Using built-in fastapi.middleware (no rate limiter there)
  • Confusing with unrelated packages
  • Misspelling package names
3.

Given this FastAPI code snippet using fastapi_limiter:

from fastapi import FastAPI
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import RateLimiter
import aioredis

app = FastAPI()

@app.on_event("startup")
async def startup():
    redis = await aioredis.from_url("redis://localhost")
    await FastAPILimiter.init(redis)

@app.get("/items", dependencies=[Depends(RateLimiter(times=3, seconds=10))])
async def read_items():
    return {"message": "Success"}

What happens if a user calls /items 4 times within 10 seconds?

medium
A. The server crashes due to Redis error
B. All 4 requests succeed with message 'Success'
C. The 4th request is blocked with a 429 Too Many Requests error
D. The 4th request is delayed but eventually succeeds

Solution

  1. Step 1: Understand RateLimiter parameters

    RateLimiter(times=3, seconds=10) allows 3 requests every 10 seconds per user.
  2. Step 2: Analyze 4 requests in 10 seconds

    The 4th request exceeds the limit and triggers a 429 error response.
  3. Final Answer:

    The 4th request is blocked with a 429 Too Many Requests error -> Option C
  4. Quick Check:

    Requests > limit = 429 error [OK]
Hint: Requests over limit cause 429 error response [OK]
Common Mistakes:
  • Assuming all requests succeed
  • Thinking server crashes on limit
  • Believing requests get delayed instead of blocked
4.

Identify the error in this FastAPI rate limiting setup:

from fastapi import FastAPI
from fastapi_limiter import FastAPILimiter
import aioredis

app = FastAPI()

@app.on_event("startup")
async def startup():
    redis = aioredis.from_url("redis://localhost")
    await FastAPILimiter.init(redis)

@app.get("/data", dependencies=[Depends(RateLimiter(times=2, seconds=5))])
async def get_data():
    return {"data": "info"}
medium
A. Missing await before aioredis.from_url call
B. RateLimiter times parameter must be 5 or more
C. FastAPILimiter.init should not be awaited
D. Redis URL must use http:// instead of redis://

Solution

  1. Step 1: Check aioredis.from_url usage

    aioredis.from_url is an async function and must be awaited to get the Redis client.
  2. Step 2: Identify missing await

    The code calls aioredis.from_url without await, causing a coroutine object instead of Redis client.
  3. Final Answer:

    Missing await before aioredis.from_url call -> Option A
  4. Quick Check:

    Async calls need await [OK]
Hint: Always await async Redis client creation [OK]
Common Mistakes:
  • Forgetting await on async functions
  • Misunderstanding RateLimiter parameters
  • Using wrong Redis URL scheme
5.

You want to limit users to 10 requests per minute globally across multiple FastAPI instances behind a load balancer. Which setup is best?

1. Use in-memory counters in each instance
2. Use Redis with fastapi_limiter shared by all instances
3. Use local file storage for counts
4. Disable rate limiting
hard
A. Option 2: Use Redis with fastapi_limiter shared by all instances
B. Option 1: Use in-memory counters in each instance
C. Option 3: Use local file storage for counts
D. Option 4: Disable rate limiting

Solution

  1. Step 1: Understand distributed rate limiting need

    Multiple FastAPI instances require a shared store to track request counts globally.
  2. Step 2: Evaluate options

    In-memory counters are local to each instance, causing inconsistent limits. Local files are not suitable for concurrency. Disabling rate limiting removes protection.
  3. Step 3: Choose Redis shared by all instances

    Redis is a fast, centralized store that all instances can use to enforce limits consistently.
  4. Final Answer:

    Option 2: Use Redis with fastapi_limiter shared by all instances -> Option A
  5. Quick Check:

    Distributed rate limiting needs shared Redis [OK]
Hint: Use shared Redis for consistent limits across instances [OK]
Common Mistakes:
  • Using local memory causing inconsistent limits
  • Using file storage which is slow and unsafe
  • Disabling rate limiting ignoring abuse risks
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard