Skip to main content

Identity-Aware Rate Limiting

Framework M implements a Decentralized Rate Limiting system that is aware of application identity (users and tenants) rather than just network IP addresses.

The Problem: IP Throttling in Modern Environments

Traditional rate limiting based on IP addresses fails in two common scenarios:

  1. The Shared IP Problem: Multiple users behind a single corporate proxy or NAT appear as one identity. Throttling the IP punishes innocent users.
  2. The Cloud Runner Problem: CI/CD runners (like GitLab Runners) often share a pool of IP addresses. High-frequency tests can trigger global throttles on external services or within the cluster.

The Solution: Port/Adapter Resolution

Framework M uses a RateLimitKeyResolver that prioritizes identity in the following order:

  1. Tenant ID: If the request is part of a multi-tenant context, we limit by tenant_id to ensure isolation.
  2. User ID: If the user is authenticated, we limit by their specific identity.
  3. Client IP: Only as a last resort for unauthenticated/public traffic.

Port & Adapter Pattern

  • Port: Defined by the RateLimitMiddleware which handles the logic of incrementing counters and checking limits.
  • Adapters:
    • MemoryStore (Indie): Stores counters in-process. Perfect for single-site deployments.
    • RedisStore (Enterprise): Stores counters in a shared Redis cluster. Required for distributed multi-node clusters to ensure global limits are respected across all Python workers.

Gateway Handshake

Framework M implements RFC-compliant X-RateLimit headers. This acts as an "Aid" to upstream gateways (like Nginx, Kong, or Traefik):

  • X-RateLimit-Limit: The total request quota allowed.
  • X-RateLimit-Remaining: How many requests are left in the current window.
  • X-RateLimit-Reset: Duration in seconds until the quota resets.

By providing these headers, upstream caches and load balancers can make informed decisions about throttling before traffic even hits the application server.