Backends¶
Selecting a Backend¶
Set RATELIMIT_BACKEND to either a short alias or a dotted class path.
When unset, the default is the in-memory backend.
# settings.py
# Short alias (resolved via the built-in backend registry)
RATELIMIT_BACKEND = "redis"
# ...or an explicit dotted class path
RATELIMIT_BACKEND = "django_smart_ratelimit.backends.redis_backend.RedisBackend"
The recognized short aliases (from backends/factory.py, BUILTIN_BACKENDS) are:
| Alias | Class path |
|---|---|
memory |
django_smart_ratelimit.backends.memory.MemoryBackend |
redis |
django_smart_ratelimit.backends.redis_backend.RedisBackend |
async_redis |
django_smart_ratelimit.backends.redis_backend.AsyncRedisBackend |
redis_cluster |
django_smart_ratelimit.backends.redis_backend.RedisClusterBackend |
mongodb |
django_smart_ratelimit.backends.mongodb.MongoDBBackend |
multi |
django_smart_ratelimit.backends.multi.MultiBackend |
database |
django_smart_ratelimit.backends.database.DatabaseBackend |
memcached |
django_smart_ratelimit.backends.memcached.MemcachedBackend |
You can register your own backend under a custom alias with
django_smart_ratelimit.backends.factory.register_backend(name, backend_class).
Available Backends¶
Redis Backend¶
Alias: redis Class: django_smart_ratelimit.backends.redis_backend.RedisBackend
The most robust backend for distributed systems. Uses Lua scripts for atomic operations.
- Pros: fast, distributed, atomic.
- Cons: external dependency. Install with
pip install django-smart-ratelimit[redis].
Connection options are read from RATELIMIT_REDIS, which accepts either
host/port/db keys or a single url:
# settings.py
RATELIMIT_BACKEND = "redis"
RATELIMIT_REDIS = {
"host": "localhost",
"port": 6379,
"db": 0,
}
# ...or, equivalently, a connection URL:
RATELIMIT_REDIS = {"url": "redis://localhost:6379/0"}
Async Redis Backend¶
Alias: async_redis Class: django_smart_ratelimit.backends.redis_backend.AsyncRedisBackend
The asynchronous version of the Redis backend, designed for use with async views.
When RATELIMIT_BACKEND = "redis", async views automatically use AsyncRedisBackend.
- Requirements:
redis-py>= 4.2.0. - Pros: non-blocking IO, high performance for async apps.
Redis Cluster Backend¶
Alias: redis_cluster Class: django_smart_ratelimit.backends.redis_backend.RedisClusterBackend
Targets a Redis Cluster. The
rate-limiting Lua scripts are each single-key, so every operation hashes to one
slot and runs correctly on a cluster — only the client construction differs.
Configure it with a seed node, a list of startup_nodes, or a URL:
# settings.py
RATELIMIT_BACKEND = "redis_cluster"
RATELIMIT_REDIS = {
"startup_nodes": [
{"host": "10.0.0.1", "port": 7000},
{"host": "10.0.0.2", "port": 7000},
],
# ...or a single seed node the cluster is discovered from:
# "host": "10.0.0.1", "port": 7000,
# ...or a URL:
# "url": "redis://10.0.0.1:7000/0",
}
- Requirements:
redis-py>= 4.1 (bundlesredis.cluster.RedisCluster). - Pros: horizontal scale and high availability across many nodes.
- Note: cluster mode has no logical databases, so a
dbinRATELIMIT_REDISis ignored. Custom clients can be supplied by subclassing and overridinginit_client().
MongoDB Backend¶
Alias: mongodb Class: django_smart_ratelimit.backends.mongodb.MongoDBBackend
Uses MongoDB Time-To-Live (TTL) collections.
- Pros: distributed, automatic cleanup via TTL.
- Cons: slower than Redis. Requires
pymongo(pip install django-smart-ratelimit[mongodb]).
Connection options are read from RATELIMIT_MONGODB:
# settings.py
RATELIMIT_BACKEND = "mongodb"
RATELIMIT_MONGODB = {
"host": "localhost",
"port": 27017,
"database": "ratelimit",
}
Database Backend¶
Alias: database Class: django_smart_ratelimit.backends.database.DatabaseBackend
Stores rate limit state in your Django database. This is the only built-in backend with native leaky-bucket support.
- Pros: no extra infrastructure, works with your existing database.
- Cons: higher per-request overhead than Redis.
Memcached Backend¶
Alias: memcached Class: django_smart_ratelimit.backends.memcached.MemcachedBackend
Uses Memcached's atomic add/incr for clock-aligned fixed-window counting.
A good fit if you already run Memcached and want distributed limiting without
adding Redis. Requires the optional pymemcache dependency
(pip install django-smart-ratelimit[memcached]).
# settings.py
RATELIMIT_BACKEND = "memcached"
RATELIMIT_MEMCACHED = {
"HOST": "127.0.0.1",
"PORT": 11211,
# ...or several nodes (consistent-hashed via pymemcache.HashClient):
# "SERVERS": ["10.0.0.1:11211", "10.0.0.2:11211"],
"CONNECT_TIMEOUT": 1,
"TIMEOUT": 1,
}
- Pros: simple, fast, distributed; reuses an existing Memcached.
- Cons: fixed-window only — Memcached has no server-side scripting, so
sliding_window,token_bucket, andleaky_bucketdegrade to fixed-window counting. Memcached can also evict keys under memory pressure (a limit may reset early). Use Redis or the database backend if you need sliding windows or bucket algorithms.
Memory Backend¶
Alias: memory Class: django_smart_ratelimit.backends.memory.MemoryBackend
Local memory (dict) storage. This is the default when RATELIMIT_BACKEND is unset.
- Pros: fastest, zero setup.
- Cons: not distributed (limits are per-process), data lost on restart.
Tuning options:
# settings.py
RATELIMIT_MEMORY_MAX_KEYS = 10000 # default
RATELIMIT_MEMORY_CLEANUP_INTERVAL = 300 # seconds, default
Multi Backend¶
Alias: multi Class: django_smart_ratelimit.backends.multi.MultiBackend
A wrapper that writes to multiple backends or fails over between them. It is
selected automatically when RATELIMIT_MULTI_BACKENDS (or RATELIMIT_BACKENDS)
is configured.
Each entry needs a type (the backend alias) and may supply options (alias
config) and a name. The strategy is either first_healthy or round_robin.
# settings.py
RATELIMIT_MULTI_BACKENDS = [
{"name": "primary", "type": "redis", "options": {"host": "localhost", "port": 6379}},
{"name": "fallback", "type": "memory", "options": {}},
]
RATELIMIT_MULTI_BACKEND_STRATEGY = "first_healthy" # default
Backend Names as Enums¶
Backend aliases above are plain strings. If you prefer the enums used for keys
and algorithms, those live in django_smart_ratelimit.enums (see the
configuration docs); backend selection itself accepts the alias strings shown
here. For algorithm selection, RATELIMIT_ALGORITHM accepts both the string
and the enum value:
from django_smart_ratelimit.enums import Algorithm
# Equivalent:
RATELIMIT_ALGORITHM = "sliding_window"
RATELIMIT_ALGORITHM = Algorithm.SLIDING_WINDOW
Note that leaky_bucket (Algorithm.LEAKY_BUCKET) via the decorator requires a
backend with native leaky-bucket support (the database backend). On other
backends it warns and falls back to standard window limiting.
Backend API¶
All backends inherit from BaseBackend (django_smart_ratelimit.backends.base.BaseBackend):
check_rate_limit(key, limit, period): returns a(allowed, metadata)tuple, whereallowedis aboolandmetadatais a dict (e.g.count,remaining).health_check(): returns a dict with connectivity information.