Rate Limiting & Throttling0%

Rate Limiting & Throttling

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

DRF Throttling: AnonRate, UserRate, and Scoped Throttles

Unrestricted APIs are vulnerable to brute-force attacks, scraping, and Denial of Service (DoS) outages. Throttling (Rate Limiting) restricts the number of requests a client can issue within a given time window. Django REST Framework includes a robust, cache-backed throttling engine supporting anonymous rate limits, authenticated user tiers, and scoped endpoint limits.


1. How Throttling Operates in DRF

DRF tracks request counts in Django's cache backend (typically Redis or Memcached). On every incoming request:

  1. 1
    DRF identifies the client: by IP address for anonymous users, or by user_id for authenticated users.
  2. 2
    It checks request history in the cache against the configured rate.
  3. 3
    If the threshold is exceeded, DRF raises Throttled, returning HTTP 429 Too Many Requests with a Retry-After header.

2. Built-in Throttle Classes

  • AnonRateThrottle: Limits unauthenticated users based on their IP address (REMOTE_ADDR or X-Forwarded-For).
  • UserRateThrottle: Limits authenticated users based on their unique user.pk.
  • ScopedRateThrottle: Applies custom limits to specific sensitive views via a throttle_scope attribute (e.g. login, checkout, password reset).

3. Global Configuration in settings.py

Python
# config/settings.py
REST_FRAMEWORK = {
"DEFAULT_THROTTLE_CLASSES": [
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
],
"DEFAULT_THROTTLE_RATES": {
"anon": "60/minute", # Max 60 requests/min per IP
"user": "1000/hour", # Max 1000 requests/hour per authenticated user
"burst": "10/second", # Burst protection
"auth_login": "5/minute", # Sensitive brute-force protection
"payment": "3/minute", # Payment mutation guard
},
}

Allowed rate time periods: second, minute, hour, day (e.g. "100/day", "5/sec").


4. Applying ScopedRateThrottle to Sensitive Endpoints

Guarding authentication endpoints against credential stuffing and brute-force attacks:

Python
# accounts/views.py
from rest_framework.views import APIView
from rest_framework.throttling import ScopedRateThrottle
from rest_framework.response import Response
 
class LoginAPIView(APIView):
# Enforce scoped rate limit
throttle_classes = [ScopedRateThrottle]
throttle_scope = "auth_login" # Maps to 'auth_login': '5/minute' in settings!
 
def post(self, request):
# Even if attacker has thousands of passwords, they can only attempt 5/min!
...

5. Tiered Subscription Rate Limiting (SaaS Plans)

For SaaS platforms with Free, Pro, and Enterprise pricing tiers, create a custom throttle class:

Python
# api/throttles.py
from rest_framework.throttling import UserRateThrottle
 
class SubscriptionTierThrottle(UserRateThrottle):
def get_rate(self):
user = self.request.user
if not user or not user.is_authenticated:
return "60/minute"
 
tier = getattr(user, "subscription_tier", "free")
if tier == "enterprise":
return "10000/hour"
elif tier == "pro":
return "3000/hour"
return "500/hour"

Interactive Quiz

Practice Quiz

Question 1
What HTTP status code is returned when a client breaches an API throttle limit?
Question 2
How does AnonRateThrottle identify unauthenticated callers?
Question 3
Where does DRF store request timestamps and counters for active throttles?
Question 4
How does ScopedRateThrottle determine which rate limit to enforce on a view?
Question 5
What header informs the client how many seconds they must wait before sending another request after being throttled?
Next Lesson

Best Practices

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Previous LessonNext Lesson
API Versioning StrategiesBest Practices

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext