Registry / http-networking / limits

limits

JSON →
library5.8.0pypypi✓ verified 52d ago

limits is a Python library for rate limiting via multiple strategies with commonly used storage backends such as Redis, Memcached, MongoDB, and Valkey. It provides identical APIs for use in synchronous and asynchronous codebases, enabling robust control over request rates. The library maintains an active development status with regular releases, with version 5.8.0 being the latest stable release at the time of verification.

http-networkingdatabase
pip install limits
Install & Compatibility
Where this runs
tested against v5.8.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.9150 runs
installs and imports cleanly · install 0.0s · import 0.407s · 20.3MB
glibc
py 3.103.9150 runs
installs and imports cleanly · install 2.2s · import 0.369s · 21MB
18MB installed
● package 18MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

strategies
from limits import strategies
storage
from limits import storage
RateLimitItem
from limits import RateLimitItem
RateLimitExceeded
from limits.errors import RateLimitExceeded
from limits.errors import LimitedError
`LimitedError` is from `throttled-py` library, `RateLimitExceeded` is for `limits`.
parse
from limits import parse
parse_many
from limits import parse_many

This quickstart demonstrates how to set up a simple rate limit using in-memory storage. It defines a rate limit, initializes a fixed-window rate limiter, and then simulates multiple actions for a user, demonstrating how the `test` and `hit` methods interact with `RateLimitExceeded` exceptions. It also shows how to get remaining quota and reset time.

from limits import parse, strategies, storage, RateLimitExceeded import time import os # 1. Initialize a storage backend # For simplicity, using in-memory storage. For production, use Redis/Memcached. # A Redis example: # REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379') # store = storage.RedisStorage(REDIS_URL) store = storage.MemoryStorage() # 2. Define a rate limit (e.g., 5 requests per minute) # parse() converts a string like '5/minute' into a RateLimitItem rate_limit_string = '5/minute' rate_limit = parse(rate_limit_string) # 3. Initialize a rate limiter strategy # FixedWindowRateLimiter is a common strategy limiter = strategies.FixedWindowRateLimiter(store) def do_limited_action(user_id): try: # 4. Test the limit for a specific identifier (e.g., user_id) if limiter.test(rate_limit, user_id): # 5. Consume the limit (i.e., record a hit) limiter.hit(rate_limit, user_id) print(f"[{user_id}] Action performed at {time.strftime('%H:%M:%S')}. Remaining: {limiter.get_remaining(rate_limit, user_id)}") else: raise RateLimitExceeded(rate_limit) except RateLimitExceeded as e: # Query available capacity and reset time remaining = limiter.get_remaining(e.limit, user_id) reset_at = limiter.get_reset_time(e.limit, user_id) print(f"[{user_id}] Rate limit exceeded for {e.limit}. Try again in {reset_at - time.time():.1f} seconds. Remaining: {remaining}") # Simulate some requests user = "test_user_1" print(f"--- Simulating requests for {user} ({rate_limit_string}) ---") for i in range(7): do_limited_action(user) time.sleep(1) # Simulate some delay print("\n--- Waiting for reset time ---") time.sleep(60) print("\n--- Simulating requests after reset ---") for i in range(3): do_limited_action(user) time.sleep(1)
limits --version
Debug
Known issues
breakingVersion 5.0.0 introduced several backward-incompatible changes, including dropping support for the `Fixed Window with Elastic Expiry` strategy and the `etcd` storage backend. Additionally, the default implementation for `async+memcached` was changed from `emcache` to `memcachio`.
fix
Review your application's rate limiting strategies and storage configurations. If using `Fixed Window with Elastic Expiry` or `etcd`, migrate to an alternative strategy/storage. If using `async+memcached`, ensure `memcachio` is compatible or manually configure `emcache` if preferred and still supported via an extra.
affects: >=5.0.0
gotchaUsing `MemoryStorage` (the default in basic examples) in a multi-process or distributed environment will not provide a global rate limit. Each process will have its own independent rate counter, which can lead to limits being exceeded across the entire system.
fix
For production or distributed applications, configure a shared storage backend such as Redis, Memcached, or MongoDB. These backends enable centralized rate limit tracking across multiple application instances.
affects: All
gotchaWhen migrating from `limits` versions prior to 5.6.0, note that project metadata moved to `pyproject.toml` and the project now uses `hatch` for package builds. While this primarily affects contributors, it's worth noting for build system interactions.
fix
For development or build automation, ensure your tooling is compatible with `pyproject.toml` and `hatch`. Direct users are generally unaffected unless they interact with the build system.
affects: <5.6.0 to >=5.6.0
deprecatedOlder versions of `limits` (e.g., prior to v2.7.0 and v2.4.0) had specific requirements for `redis` and `coredis` versions. While current versions relax these, always verify compatibility.
fix
Always check the `limits` library's `requires` and `Provides-Extra` on PyPI or the `pyproject.toml` for the most up-to-date dependency compatibility, especially when upgrading or installing specific optional backends.
affects: <2.7.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'limits'
The 'limits' library is not installed in your Python environment or is not accessible via the Python path.
fix
Install the library using pip: `pip install limits`
ConfigurationError: redis library is not available
The specified storage backend (Redis in this case) requires its corresponding Python client library to be installed, which is missing, or the connection URI is invalid/unreachable.
fix
Install the necessary backend client (e.g., `pip install redis` for Redis) and ensure your connection URI is correct and the server is accessible.
limits.errors.RateLimitExceeded: 5 per 1 minute
The configured rate limit for a specific operation or endpoint has been exceeded, preventing further execution until the limit resets.
fix
This is an expected behavior of rate limiting. To handle it gracefully, catch the `RateLimitExceeded` exception and implement retry logic, inform the user to wait, or adjust your application's request rate. For example, `try: ... except RateLimitExceeded: print('Rate limit hit, please wait.')`
TypeError: 'Rate' object is not callable
This error can occur if you attempt to call a `Rate` object directly as a function, rather than using it as an argument for rate limiting functions or decorators.
fix
Ensure you are passing the `Rate` object to the appropriate `limits` function or decorator (e.g., `limiter.hit(rate)`) instead of trying to execute it like a function.
AttributeError: 'X' object has no attribute 'Y'
You are attempting to access an attribute or method on a `limits` object (e.g., a `Storage` or `Limiter` instance) that does not exist or is misspelled. This can also happen with incorrect usage of decorators.
fix
Review the `limits` library's API documentation for the specific object you are using to ensure you are calling the correct attributes or methods and that your object is correctly initialized.
Upgrade
Version history
5.8.0latest on PyPI
Audit
Dependencies
pythonrequiredRequires Python 3.10 or newer.
redisoptionalOptional, for Redis storage backend.
memcacheoptionalOptional, for Memcached storage backend.
pymongooptionalOptional, for MongoDB storage backend.
coredisoptionalOptional, for async Redis storage backend.
valkeyoptionalOptional, for Valkey storage backend.
Agent activity
22 hits · last 30 days
node
10
seranking-bot
4
ahrefsbot
2
Meta
1
Amazon
1
Resources