Per-route limits

A login attempt is cheap. A chat completion costs OpenRouter dollars. A document upload writes to ChromaDB and disk. One global limit treats all three the same, which means either logins are too tight or chat is too loose. Per-route limits fix it.

rate_limiter.py
python
ROUTE_BUDGETS = {
    "login": (60, 20),     # 20 attempts per minute
    "chat": (60, 10),      # 10 chat completions per minute
    "upload": (60, 3),     # 3 uploads per minute
}

def check_rate_limit(self, username: str, route: str) -> bool:
    window, max_requests = ROUTE_BUDGETS.get(route, (60, 10))
    key = f"rl:{username}:{route}"
    # ...same sliding-window logic, scoped by (user, route)

The composite key keeps every (user, route) pair in its own bucket. Adding a new route is a one-line config change, not a code change.

Quiz: Quiz

Loading practice…