Skip to main content

Overview

Rate limiting is a critical security feature that protects your application from abuse, brute force attacks, and resource exhaustion. django-allauth includes comprehensive rate limiting that’s enabled by default and requires no external dependencies beyond Django’s cache framework.
Rate limiting requires a proper cache backend. It will not work correctly with Django’s DummyCache. Use Redis, Memcached, or database caching in production.

How Rate Limiting Works

Rate limits restrict the number of times an action can be performed within a time window, tracked per:
  • IP address - Prevent attacks from specific sources
  • User - Limit actions per authenticated user
  • Key - Custom identifier (email, username, phone)

Rate Limit Syntax

Rate limits use a concise string format:
Examples:
Duration units:
  • s - seconds
  • m - minutes
  • h - hours
  • d - days
Per options:
  • ip - Client IP address
  • user - Authenticated user
  • key - Action-specific key (email, username, etc.)

Default Rate Limits

django-allauth ships with sensible defaults configured for security: From source (app_settings.py:260-304):

Customizing Rate Limits

Override Specific Limits

Modify individual rate limits while keeping defaults:

Disable Specific Limits

Set to None to disable a specific rate limit:
Disabling rate limits significantly increases your application’s attack surface. Only do this in controlled environments or with alternative protection mechanisms.

Disable All Rate Limits

Useful for development or when using external rate limiting (e.g., Cloudflare, AWS WAF).

Rate Limit Actions

Authentication Actions

Default: 30/m/ipGeneral login attempts (successful or failed).
Applied on every login form submission.
Default: 10/m/ip,5/5m/keyCritical for security - Prevents brute force password attacks.
When exceeded, users are temporarily locked out even with correct credentials.
Important: This only protects allauth’s login view. It does not protect Django’s admin login. See the admin protection docs for securing admin login.
From source (rate_limits.rst:43-47):
Restricts the allowed number of failed login attempts. When exceeded, the user is prohibited from logging in for the remainder of the rate limit. Important: while this protects the allauth login view, it does not protect Django’s admin login from being brute forced.
Default: 20/m/ipUser registration attempts.
Prevents automated account creation and spam registrations.
Default: 20/m/ip,3/m/keyRequesting passwordless login codes.
The key is the email address requesting the code.

Password Actions

Default: 20/m/ip,5/m/keyRequesting password reset emails.
The key is the email address for which the reset is requested.Prevents:
  • Email bombing (spamming user with reset emails)
  • Account enumeration attempts
Default: 20/m/ipSubmitting the password reset form (after clicking the link).
Prevents brute-forcing the new password field.
Default: 5/m/userChanging password for authenticated users.
Prevents password change abuse if an account is compromised.

Email Actions

Default: 1/3m/key (link) or 1/10s/key (code)Sending email verification messages.
The key is the email address being verified.Automatic configuration from source (app_settings.py:270-276):
Default: 10/m/userEmail management actions (add, remove, set primary).
Prevents rapid-fire email additions/removals.

Other Actions

Default: 10/m/userRe-entering credentials for sensitive operations.
Default: 1/m/userChanging phone number.
Default: 1/30s/key,3/m/ipSending phone verification codes.
The key is the phone number.

IP Address Detection

Critical Security Consideration: Accurate IP detection is essential for rate limiting to work correctly.django-allauth cannot reliably determine the client IP address out of the box because the correct method depends on your infrastructure (load balancers, proxies, CDNs).The X-Forwarded-For header can be trivially spoofed, allowing attackers to bypass rate limits entirely.

Trusted Proxy Configuration

Configure how many proxies are under your control:
How it works: With ALLAUTH_TRUSTED_PROXY_COUNT = 1:
  • X-Forwarded-For: client, proxy1, proxy2
  • Takes the IP from position: count from the right
  • Result: proxy1 (second from right)
From source (rate_limits.rst:36-45):
As the X-Forwarded-For header can be spoofed, you need to configure the number of proxies that are under your control and hence, can be trusted. The default is 0, meaning, no proxies are trusted. As a result, the X-Forwarded-For header will be disregarded by default.

Trusted Header Configuration

If your proxy sets a custom header (e.g., Cloudflare, nginx):
Only use ALLAUTH_TRUSTED_CLIENT_IP_HEADER if you’re certain the header is set by a trusted component and cannot be spoofed by clients.

Custom IP Detection

Override the adapter for complex scenarios:

Testing IP Detection

Rate Limit Implementation

Internal Architecture

From source (core/internal/ratelimit.py:1-11):
Rate limiting uses cache-based tracking with non-atomic operations. This means:
  • ✅ Performant and scalable
  • ✅ No database overhead
  • ⚠️ Slight overruns possible under high concurrency (acceptable trade-off)

Cache Key Format

From source (core/internal/ratelimit.py:93-117):
Example cache keys:

Consumption Algorithm

From source (core/internal/ratelimit.py:120-147):
History tracking:

Programmatic Rate Limiting

Check Rate Limit Without Consuming

Consume Rate Limit

Consume with Exception

Clear Rate Limit

Custom Rate Limit Actions

Define your own rate-limited actions:

429 Response Customization

Custom Template

Create 429.html in your templates directory:

Custom Handler

Define a custom 429 handler in your root URLconf:

Headless API Response

For headless/API mode:

Testing with Rate Limits

Disable for Tests

Test Rate Limit Behavior

Monitoring Rate Limits

Log Rate Limit Events

Metrics Collection

Cache Backend Recommendations

Advantages:
  • ✅ High performance
  • ✅ Atomic operations
  • ✅ TTL support
  • ✅ Distributed (multiple app servers)

Memcached

Advantages:
  • ✅ Fast
  • ✅ Simple setup
  • ✅ Distributed

Database Cache

Use when:
  • ⚠️ No Redis/Memcached available
  • ⚠️ Lower traffic requirements
  • ✅ Need cache persistence
Never use DummyCache in production. Rate limiting will not function.

Best Practices

Begin with stricter limits and relax based on monitoring:
Gradually increase if legitimate users are affected.
Use both IP and key-based limits for defense in depth:
Track rate limit hits to detect attacks:
Always configure IP detection for your infrastructure:
Redis or Memcached in production:

Troubleshooting

Check cache backend:
If using DummyCache, rate limits won’t work.
Check IP detection:
If all requests show the same IP (e.g., load balancer), configure trusted proxies.
Increase limits or use more specific keys:
Check cache TTL and duration:

Next Steps

Authentication Flows

See where rate limits are applied in login/signup flows

Email Verification

Learn about email verification rate limiting