Skip to content

Rate Limiting

The ratelimit module provides shared infrastructure for rate limiting across Django and FastAPI. This includes Lua scripts for atomic Redis operations, data models for rate limit configuration, and key generation utilities.

Lua Scripts

Two Lua scripts handle atomic rate limit checking:

  • RATE_LIMITER_LUA: Basic rate limiting without override support. Increments a counter and checks against a fixed limit.
  • PROJECT_RATE_LIMITER_LUA: Extended rate limiting that checks for per-project overrides stored in Redis hashes before applying limits.

Both scripts return the current request count, TTL, and whether the limit was exceeded in a single atomic operation.

Key Format

Rate limit keys follow consistent patterns:

  • Counter: ratelimit:{endpoint}:{organization_id}:{project_id}
  • Override: ratelimit_override:{endpoint}:{organization_id}:{project_id}

The endpoint portion matches your framework's route pattern (e.g., /datasets/{dataset_id}/search for FastAPI).

Core

application_kit.ratelimit

Shared rate limiting components for Django and FastAPI.

This module contains the common Lua scripts, data models, and key generation functions used by both the Django and FastAPI rate limiting implementations.

RateLimitOverride

Bases: BaseModel

Rate limit override configuration stored in Redis.

RateLimitResult dataclass

RateLimitResult(
    is_over_limit, request_count, ttl, max_requests
)

Result of a rate limit check.

make_rate_limit_key

make_rate_limit_key(
    endpoint_name, organization_id, project_id
)

Generate the Redis key for rate limit counter.

Source code in application_kit/ratelimit.py
120
121
122
123
124
125
126
def make_rate_limit_key(
    endpoint_name: str,
    organization_id: int | None,
    project_id: int | None,
) -> str:
    """Generate the Redis key for rate limit counter."""
    return f"ratelimit:{endpoint_name}:{organization_id}:{project_id}"

make_override_key

make_override_key(
    endpoint_name, organization_id, project_id
)

Generate the Redis key for rate limit override lookup.

Source code in application_kit/ratelimit.py
129
130
131
132
133
134
135
def make_override_key(
    endpoint_name: str,
    organization_id: int | None,
    project_id: int | None,
) -> str:
    """Generate the Redis key for rate limit override lookup."""
    return f"ratelimit_override:{endpoint_name}:{organization_id}:{project_id}"

FastAPI

application_kit.fastapi.ratelimit

Django

application_kit.django.ratelimit

RateLimitExceeded

RateLimitExceeded(limit, remaining, reset)

Bases: HttpException

Raised when rate limit is exceeded.

Source code in application_kit/django/ratelimit.py
50
51
52
53
54
55
56
57
58
59
def __init__(self, limit: int, remaining: int, reset: int) -> None:
    headers = {
        "RateLimit-Limit": str(limit),
        "RateLimit-Remaining": str(remaining),
        "RateLimit-Reset": str(reset),
    }
    super().__init__(status=429, message="Rate limit exceeded. Try again later.", headers=headers)
    self.limit = limit
    self.remaining = remaining
    self.reset = reset