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:
- The Shared IP Problem: Multiple users behind a single corporate proxy or NAT appear as one identity. Throttling the IP punishes innocent users.
- 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:
- Tenant ID: If the request is part of a multi-tenant context, we limit by
tenant_idto ensure isolation. - User ID: If the user is authenticated, we limit by their specific identity.
- Client IP: Only as a last resort for unauthenticated/public traffic.
Port & Adapter Pattern
- Port: Defined by the
RateLimitMiddlewarewhich 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.