Skip to main content

Redis-backed sliding-window rate limiter for Python

Project description

sliding-rate-limiter-redis

A Redis-backed sliding window rate limiter for Python.

PyPI Python CI License: MIT

Why sliding window?

Most rate limiters use a fixed window (e.g. "100 requests per minute, resetting on the clock"). This creates a burst problem: a client can make 100 requests at 00:59 and another 100 at 01:00 — 200 requests in two seconds.

The sliding window log algorithm solves this by tracking the exact timestamp of every request in a Redis sorted set. Only requests within the last window seconds are counted, so the limit is enforced continuously rather than in discrete buckets.

All Redis operations execute atomically via a Lua script, so check-and-increment is race-condition free under high concurrency.

Installation

pip install sliding-rate-limiter-redis

Requires redis-py >= 4.0.0 and a running Redis instance.

Quick start

import redis
from rate_limiter import SlidingWindowLimiter, RateLimitError

r = redis.Redis()
limiter = SlidingWindowLimiter(r, limit=100, window=60, key_prefix="rl")

# Non-throwing: inspect the result yourself
result = limiter.check("user:42")
print(result)
# RateLimitResult(allowed=True, remaining=99, retry_after=None, reset_at=..., limit=100)

# Throwing: raises RateLimitError if the limit is exceeded
try:
    limiter.consume("user:42")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")

FastAPI middleware example

from fastapi import Request
from fastapi.responses import JSONResponse

@app.middleware("http")
async def rate_limit(request: Request, call_next):
    try:
        result = limiter.consume(request.client.host)
        response = await call_next(request)
        response.headers["X-RateLimit-Remaining"] = str(result.remaining)
        return response
    except RateLimitError as e:
        return JSONResponse(
            status_code=429,
            content={"error": "Too Many Requests"},
            headers={"Retry-After": str(e.retry_after)},
        )

API

SlidingWindowLimiter(redis, *, limit, window, key_prefix="rl")

Parameter Type Description
redis redis.Redis Connected redis-py client
limit int Maximum requests per window
window int Window duration in seconds
key_prefix str Redis key prefix. Default: "rl"

check(identifier) → RateLimitResult

Records the request and returns a result. Does not raise on limit exceeded.

consume(identifier) → RateLimitResult

Same as check() but raises RateLimitError if the limit is exceeded.

RateLimitResult

Field Type Description
allowed bool Whether the request was allowed
remaining int Requests remaining in the current window
retry_after int | None Seconds until next request allowed; None if allowed
reset_at datetime UTC datetime when the window resets
limit int The configured limit

RateLimitError

Raised by consume() when the limit is exceeded. Carries retry_after, reset_at, and limit.

Full documentation

See the GitHub repository for architecture details, Node.js package, benchmarks, and more.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sliding_rate_limiter_redis-1.0.1.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sliding_rate_limiter_redis-1.0.1-py3-none-any.whl (4.3 kB view details)

Uploaded Python 3

File details

Details for the file sliding_rate_limiter_redis-1.0.1.tar.gz.

File metadata

File hashes

Hashes for sliding_rate_limiter_redis-1.0.1.tar.gz
Algorithm Hash digest
SHA256 30eb4f7ced84e589f08ee2252a6a7e68b07a992361e5ab93f33bc5dd45394107
MD5 86fbdbedc2e5945e7dee8e85c49ff10e
BLAKE2b-256 2fd17e1ea60156ae650276ca06f4f1fa124e8a4b5555e370aebe73e8d04ab86d

See more details on using hashes here.

Provenance

The following attestation bundles were made for sliding_rate_limiter_redis-1.0.1.tar.gz:

Publisher: publish-python.yml on aproothi/sliding-rate-limiter-redis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sliding_rate_limiter_redis-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for sliding_rate_limiter_redis-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 54b5dfc6ac1e9876540aaeaca745e2ba0e6eb724487ff9c86bf7c755a16d1950
MD5 8bee6c6d2dd58b184cf56acfd0cd285f
BLAKE2b-256 f6fa3c3a1bf11d7b34551fb91469512c5b33933ad65e7459f4419f71bab816a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sliding_rate_limiter_redis-1.0.1-py3-none-any.whl:

Publisher: publish-python.yml on aproothi/sliding-rate-limiter-redis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page