Skip to content

Configuration

This page provides a complete reference of all Django Smart Ratelimit settings.

Core Settings

# Enable/disable rate limiting globally (default: True)
RATELIMIT_ENABLE = True

# Default algorithm for rate limiting (default: 'sliding_window')
# Options: 'sliding_window', 'fixed_window', 'token_bucket', 'leaky_bucket'
RATELIMIT_ALGORITHM = 'sliding_window'

# RATELIMIT_ALGORITHM also accepts the Algorithm enum (StrEnum), which is
# interchangeable with the equivalent string:
#
#   from django_smart_ratelimit.enums import Algorithm
#   RATELIMIT_ALGORITHM = Algorithm.TOKEN_BUCKET
#
# Algorithm.SLIDING_WINDOW == 'sliding_window', Algorithm.FIXED_WINDOW == 'fixed_window',
# Algorithm.TOKEN_BUCKET == 'token_bucket', Algorithm.LEAKY_BUCKET == 'leaky_bucket'.

# Default rate limit when not specified in decorator (default: '100/m')
RATELIMIT_DEFAULT_LIMIT = '100/m'

# Key prefix for all rate limit cache keys (default: 'ratelimit:')
RATELIMIT_KEY_PREFIX = 'ratelimit:'

Key Selection

Anywhere a key string is accepted (for example the key argument of the rate_limit decorator), you can pass either the raw string or the RateLimitKey enum (a StrEnum), which is interchangeable with its string value:

from django_smart_ratelimit.enums import RateLimitKey

# Complete keys, usable directly:
#   RateLimitKey.IP         == 'ip'
#   RateLimitKey.USER       == 'user'
#   RateLimitKey.USER_OR_IP == 'user_or_ip'

# HEADER and PARAM are prefixes: combine them with a sub-value that names the
# header or query parameter to key on.
key = f"{RateLimitKey.HEADER}:X-Api-Key"  # -> 'header:X-Api-Key'
key = f"{RateLimitKey.PARAM}:tenant"      # -> 'param:tenant'

Backend Configuration

RATELIMIT_BACKEND accepts one of the short names "redis", "memory", "mongodb", "database", "multi", or a dotted path to a backend class. When RATELIMIT_BACKEND is unset, the in-memory backend is used by default.

RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
}

Alternatively, supply a connection URL via the url key instead of host/port/db:

RATELIMIT_BACKEND = 'redis'
RATELIMIT_REDIS = {
    'url': 'redis://localhost:6379/0',
}

Async Support: When using RATELIMIT_BACKEND = 'redis', the library automatically uses AsyncRedisBackend for asynchronous views (async def). No separate configuration is required.

MongoDB

RATELIMIT_BACKEND = 'mongodb'
RATELIMIT_MONGODB = {
    'uri': 'mongodb://localhost:27017',
    'database': 'ratelimit',
    'collection': 'ratelimits',
}

Memory Backend

RATELIMIT_BACKEND = 'memory'

# Maximum number of keys to store (default: 10000)
RATELIMIT_MEMORY_MAX_KEYS = 10000

# Cleanup interval in seconds (default: 300)
RATELIMIT_MEMORY_CLEANUP_INTERVAL = 300

Note: The memory backend stores data in process memory and does not share state across workers. Best for development or single-process deployments.

Multi-Backend with Failover

RATELIMIT_BACKENDS = [
    {
        'name': 'primary_redis',
        'backend': 'redis',
        'config': {'host': 'redis-primary.example.com'}
    },
    {
        'name': 'fallback_memory',
        'backend': 'memory',
        'config': {}
    }
]

# Strategy for selecting backend (default: 'first_healthy')
RATELIMIT_MULTI_BACKEND_STRATEGY = 'first_healthy'

Window Alignment Configuration

Controls how time windows are calculated for rate limiting.

# Align windows to clock boundaries (default: True)
RATELIMIT_ALIGN_WINDOW_TO_CLOCK = True

Clock-Aligned Windows (Default)

When RATELIMIT_ALIGN_WINDOW_TO_CLOCK = True:

  • A 60/m rate limit window starts at :00 seconds (e.g., 12:00:00, 12:01:00)
  • All users share the same window boundaries
  • X-RateLimit-Reset headers show predictable clock-aligned times
  • Best for: Most use cases, predictable reset times, consistent user experience

First-Request-Aligned Windows

When RATELIMIT_ALIGN_WINDOW_TO_CLOCK = False:

  • A 60/m rate limit window starts when each user's first request arrives
  • Each user has independent window boundaries
  • X-RateLimit-Reset headers show the time since first request
  • Best for: APIs where you want users to get their full quota regardless of when they start

Example

With a 5/m limit and clock alignment enabled:

  • User A's first request at 12:00:30 → window is 12:00:00-12:01:00 (30s remaining)
  • User B's first request at 12:00:45 → same window 12:00:00-12:01:00 (15s remaining)

With clock alignment disabled:

  • User A's first request at 12:00:30 → window is 12:00:30-12:01:30 (60s remaining)
  • User B's first request at 12:00:45 → window is 12:00:45-12:01:45 (60s remaining)

Client IP and Proxy Trust

The "ip" / "user_or_ip" keys and the CIDR allow/deny lists derive the client IP from request headers. Forwarded headers (X-Forwarded-For, CF-Connecting-IP, X-Real-IP) are client-controlled and spoofable unless a trusted proxy overwrites them, so two settings (added in v3.1.0) control how much they are trusted:

# A list of IP/CIDR strings identifying your reverse proxies / load balancers.
# When set, forwarded headers are honored ONLY for requests arriving from one of
# these proxies, and the real client is the right-most non-trusted entry of the
# X-Forwarded-For chain. This is the secure, recommended configuration.
RATELIMIT_TRUSTED_PROXIES = ['10.0.0.0/8']

# Master switch (default True). Set False to ignore forwarded headers entirely
# and always use REMOTE_ADDR (useful when the app is never behind a proxy).
RATELIMIT_TRUST_FORWARDED_HEADERS = True

Defaults are backward compatible: when neither setting is configured, the first present forwarded header is trusted (the historical behavior). See the deployment guide for the security rationale.

Circuit Breaker Configuration

Protects your application when backends are unhealthy.

# settings.py
RATELIMIT_CIRCUIT_BREAKER = {
    'failure_threshold': 5,        # Open circuit after 5 failures
    'recovery_timeout': 60,        # Wait 60 seconds before testing recovery
    'reset_timeout': 300,          # Reset after 5 minutes of success
    'half_open_max_calls': 1,      # Test with 1 call in half-open state
}

# Storage for circuit breaker state (default: 'memory')
RATELIMIT_CIRCUIT_BREAKER_STORAGE = 'memory'

# Redis URL for distributed circuit breaker state (optional)
RATELIMIT_CIRCUIT_BREAKER_REDIS_URL = 'redis://localhost:6379/1'

Health Check Configuration

# How often to check backend health in seconds (default: 30)
RATELIMIT_HEALTH_CHECK_INTERVAL = 30

# Timeout for health check operations in seconds (default: 5)
RATELIMIT_HEALTH_CHECK_TIMEOUT = 5

Error Handling Configuration

# Fail open on backend errors (default: False)
# If True, requests are allowed when the backend fails
RATELIMIT_FAIL_OPEN = True

# Log exceptions (default: True)
RATELIMIT_LOG_EXCEPTIONS = True

# Custom exception handler
# Path to a function that takes (request, exception) and returns a response or None
RATELIMIT_EXCEPTION_HANDLER = 'myproject.utils.custom_ratelimit_handler'

Performance & Metrics

# Enable metrics collection (default: False)
RATELIMIT_COLLECT_METRICS = True

Middleware Configuration

# Configure middleware behavior
RATELIMIT_MIDDLEWARE = {
    'DEFAULT_RATE': '100/m',
    'SKIP_PATHS': ['/health/', '/metrics/'],  # paths the middleware never limits
}

# Enable/disable rate limiting globally (the middleware honors this, NOT a
# per-middleware "enabled" key):
RATELIMIT_ENABLE = True

The middleware reads SKIP_PATHS (not excluded_paths) and the top-level RATELIMIT_ENABLE setting (not a 'enabled' key inside RATELIMIT_MIDDLEWARE).

Advanced feature settings (v4.x)

These are all opt-in and default to off. Each links to a dedicated guide.

Setting Default Purpose
RATELIMIT_USE_DYNAMIC_RULES False Enable database-backed dynamic rules.
RATELIMIT_RULE_CACHE_TIMEOUT 60 Seconds to cache dynamic rules before reloading.
RATELIMIT_USE_USER_TIERS False Enable user tiers / overrides in the middleware and decorator.
RATELIMIT_LOG_EVENTS False Record a RateLimitEvent per decision for analytics.
RATELIMIT_GEOIP_PATH None Path to a GeoLite2/GeoIP2 .mmdb for geographic limiting.
RATELIMIT_ALERT_THRESHOLD unset Min blocked requests before an offender alert fires.
RATELIMIT_ALERT_EMAILS unset Recipient list for offender email alerts.
RATELIMIT_ALERT_WEBHOOK unset Webhook URL for offender alerts (POSTed JSON).
RATELIMIT_STATSD {} StatsD exporter config (ENABLED/HOST/PORT/PREFIX); see Observability.
# settings.py — example: dynamic rules + user tiers + event logging
RATELIMIT_USE_DYNAMIC_RULES = True
RATELIMIT_RULE_CACHE_TIMEOUT = 60
RATELIMIT_USE_USER_TIERS = True
RATELIMIT_LOG_EVENTS = True

# Geographic limiting
RATELIMIT_GEOIP_PATH = "/var/lib/GeoIP/GeoLite2-City.mmdb"

# Offender alerting (run `manage.py ratelimit_alerts` from cron)
RATELIMIT_ALERT_THRESHOLD = 500
RATELIMIT_ALERT_EMAILS = ["secops@example.com"]
RATELIMIT_ALERT_WEBHOOK = "https://hooks.example.com/ratelimit"

# StatsD / DogStatsD metrics
RATELIMIT_STATSD = {"ENABLED": True, "HOST": "127.0.0.1", "PORT": 8125}

Custom Configuration

You can add custom configuration values using the RATELIMIT_CONFIG_ prefix:

# These become accessible as config.custom_configs['mykey']
RATELIMIT_CONFIG_MYKEY = 'custom_value'
RATELIMIT_CONFIG_API_TIER = 'premium'