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.0.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.0-py3-none-any.whl (4.3 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for sliding_rate_limiter_redis-1.0.0.tar.gz
Algorithm Hash digest
SHA256 82ff8cc1f3c2eca02eece6e88da5db360ac06b4bddcb276e9ded48d7c7a0db08
MD5 c86db5766d84e35a02c7374fd4e8e486
BLAKE2b-256 0a41ad5d2bd6e151673c3d185c2b3d7683263301fa371b2ae85ba2abb9cabda0

See more details on using hashes here.

Provenance

The following attestation bundles were made for sliding_rate_limiter_redis-1.0.0.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.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sliding_rate_limiter_redis-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 46399d94dc87bab127236d7717f4c4d60451c31893a84cd77b5c4b69edd5589d
MD5 edf1c99ee65bf86d36492a484bbf3aaf
BLAKE2b-256 5f479b565abeebf977f5cfdcb6cb76d83011c6cb8e53fa2fff3e8e5df8edd773

See more details on using hashes here.

Provenance

The following attestation bundles were made for sliding_rate_limiter_redis-1.0.0-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