Короткий ответ
Rate limiting ограничивает число запросов от одного клиента (по API-ключу, пользователю или IP) за промежуток времени; при превышении лимита сервер возвращает 429 Too Many Requests, а информацию о лимите и остатке передаёт через заголовки типа X-RateLimit-Limit, X-RateLimit-Remaining и Retry-After.
Как это работает подробнее
распространённые алгоритмы — fixed window (счётчик на фиксированный интервал, прост, но даёт всплески на границе окна), sliding window и token bucket (более равномерное распределение, сложнее реализовать). Состояние счётчиков обычно хранят в быстром внешнем хранилище (Redis) с TTL, а не в памяти процесса, иначе лимит будет считаться отдельно на каждом инстансе приложения при горизонтальном масштабировании.
Пример кода
example.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.middleware("http")
async def rate_limit_middleware(request: Request, call_next):
api_key = request.headers.get("X-Api-Key", "anonymous")
allowed, remaining, retry_after = rate_limiter.check(api_key) # например, через Redis token bucket
if not allowed:
return JSONResponse(
status_code=429,
content={"detail": "Too many requests"},
headers={"Retry-After": str(retry_after), "X-RateLimit-Remaining": "0"},
)
response = await call_next(request)
response.headers["X-RateLimit-Remaining"] = str(remaining)
return responseЧто использовать на практике
- Рекомендация. лимиты стоит делить по уровню доступа клиента (бесплатный/платный тариф) и по типу операции (чтение обычно лимитируют мягче, чем дорогие операции записи); заголовок
Retry-Afterв ответе 429 подсказывает клиенту, через сколько секунд повторить попытку, что снижает бессмысленные повторные запросы.
Подводные камни
- Риски. хранить счётчики лимита в памяти одного процесса при наличии нескольких инстансов сервиса за балансировщиком, что фактически умножает реальный лимит на количество инстансов; не возвращать 429 с понятными заголовками, из-за чего клиенты просто получают "500-подобное" поведение и не могут адаптировать частоту запросов программно.