Rate Limiting#

plyr.fm uses slowapi to implement application-side rate limiting. This protects the backend from abuse, brute-force attacks, and denial-of-service attempts.

Configuration#

Rate limits are configured via environment variables. Defaults are set in src/backend/config.py.

Environment Variable Default Description
RATE_LIMIT_ENABLED true Enable/disable rate limiting globally.
RATE_LIMIT_DEFAULT_LIMIT 100/minute Global limit applied to all endpoints by default.
RATE_LIMIT_AUTH_LIMIT 10/minute Strict limit for auth endpoints (/auth/start, /auth/exchange).
RATE_LIMIT_UPLOAD_LIMIT 5/minute Strict limit for file uploads (/tracks/).

Architecture#

The current implementation uses in-memory storage.

  • Per-Instance: Limits are tracked per application instance (Fly Machine).
  • Scaling: With multiple replicas (e.g., 2 machines), the effective global limit scales linearly.
    • Example: A limit of 100/minute with 2 machines results in a total capacity of roughly 200/minute.
  • Keying: Limits are applied by IP address (get_remote_address).

Why in-memory?#

For our current scale, in-memory is sufficient and avoids the complexity/cost of a dedicated Redis cluster. This provides effective protection against single-source flooding (DDoS/brute-force) directed at any specific instance.

Future State (Redis)#

If strict global synchronization or complex tier-based limiting is required in the future, we will migrate to a Redis-backed limiter. slowapi supports Redis out of the box, which would allow maintaining shared counters across all application instances.

Adding Limits to Endpoints#

To apply a specific limit to a route, use the @limiter.limit decorator:

from backend.utilities.rate_limit import limiter
from backend.config import settings

@router.post("/my-expensive-endpoint")
@limiter.limit("5/minute")
async def my_endpoint(request: Request):
    ...

Requirements:

  • The endpoint function must accept a request: Request parameter.
  • Use configuration settings instead of hardcoded strings where possible.

Monitoring#

Rate limit hits return 429 Too Many Requests. These events are logged and will appear in Logfire traces with the 429 status code.