Install & Compatibility
Where this runs
tested against v0.10.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
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.682s · 21.6MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.3s · import 0.610s · 22MB
20MB installed
● package 20MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
LimiterSession
✓ from requests_ratelimiter import LimiterSession
LimiterAdapter
✓ from requests_ratelimiter import LimiterAdapter
LimiterMixin
✓ from requests_ratelimiter import LimiterMixin
RequestRate
✓ from pyrate_limiter import RequestRate
✗ from requests_ratelimiter import RequestRate
RequestRate is part of pyrate-limiter, not requests-ratelimiter directly.
Duration
✓ from pyrate_limiter import Duration
✗ from requests_ratelimiter import Duration
Duration is part of pyrate-limiter, not requests-ratelimiter directly.
This quickstart demonstrates how to use `LimiterSession` as a drop-in replacement for `requests.Session` to apply a simple rate limit. It also shows how to define more complex rate limits using `RequestRate` and `Duration` from the underlying `pyrate-limiter` library. The `httpbin.org/get` endpoint is used for demonstration purposes.
import os
from requests_ratelimiter import LimiterSession
from time import time
session = LimiterSession(per_second=5) # Limit to 5 requests per second
start = time()
for i in range(10):
try:
response = session.get('https://httpbin.org/get') # Or any other API endpoint
response.raise_for_status()
print(f'[t+{time()-start:.2f}] Sent request {i+1} (Status: {response.status_code})')
except Exception as e:
print(f'Request {i+1} failed: {e}')
# Example with custom rate using pyrate-limiter objects
from pyrate_limiter import RequestRate, Duration, Limiter
# Limit to 10 requests per minute
custom_limiter_session = LimiterSession(limiter=Limiter(RequestRate(10, Duration.MINUTE)))
start_custom = time()
for i in range(5):
try:
response = custom_limiter_session.get('https://httpbin.org/get')
response.raise_for_status()
print(f'[t+{time()-start_custom:.2f}] Sent custom-limited request {i+1} (Status: {response.status_code})')
except Exception as e:
print(f'Custom-limited request {i+1} failed: {e}')
Debug
Known issues
breakingDropped support for Python 3.8 and 3.9 as of version 0.9.0, aligning with upstream `pyrate-limiter` requirements. Requires Python >=3.10.fixUpgrade your Python environment to 3.10 or newer.
affects: >=0.9.0
gotchaBy default, each `LimiterSession` (and `LimiterAdapter`) operates independently, tracking rate limits only within its own instance. In multi-threaded environments, multiple processes, or web applications, this can lead to exceeding actual server-side rate limits.fixFor shared rate limits across threads, processes, or application restarts, use a persistent backend such as SQLite or Redis. This requires installing `requests-ratelimiter[sqlite]` or `requests-ratelimiter[redis]` and configuring the session with the appropriate backend.
affects: All versions
gotchaWhen combining `requests-ratelimiter` with other `requests`-based libraries (e.g., `requests-cache`) using mixins, the inheritance order of mixin classes is crucial. If rate-limiting is applied *before* caching, cache hits will still count against your rate limit.fixTo ensure cache hits do not count towards the rate limit, the `CacheMixin` should typically be listed before `LimiterMixin` in the class inheritance. Example: `class CachedLimiterSession(CacheMixin, LimiterMixin, Session):`
affects: All versions
breakingIn earlier versions, `LimiterSession` accepted a `rates` argument to define rate limits. This was replaced by direct `per_second`, `per_minute`, etc., arguments, or by passing a `Limiter` object. Using the old `rates` argument will raise an `InvalidParams` exception from `pyrate_limiter`.fixInstead of `LimiterSession(rates=[RequestRate(5, Duration.SECOND)])`, use `LimiterSession(per_second=5)` or `LimiterSession(limiter=Limiter(RequestRate(5, Duration.SECOND)))`.
affects: <0.9.0 (exact version unclear, but pre-0.9.0)
gotchaThe `per_host` parameter, available for both `LimiterSession` and `LimiterAdapter`, enables automatic tracking of rate limits separately for each host. If not enabled, a single rate limit applies across all hosts, which might not be the desired behavior for APIs with per-domain limits.fixSet `per_host=True` when initializing `LimiterSession` or `LimiterAdapter` if you need distinct rate limits for different API endpoints/hosts: `session = LimiterSession(per_second=5, per_host=True)`.
affects: All versions
Upgrade
Version history
0.10.0latest on PyPI · released Apr 22, 2026
Audit
Dependencies
requestsrequiredCore HTTP library that requests-ratelimiter extends.
pyrate-limiterrequiredUnderlying rate-limiting logic.
requests-cacheoptionalCommonly used with requests-ratelimiter for caching responses. The order of mixins matters.
redisoptionalRequired for Redis persistent backend for rate limits.