Overview
While most rate limits are defined statically in theRateLimiter constructor, you can also define them dynamically at runtime using the config parameter.
Static vs Dynamic Definitions
Static Definition (Recommended)
Define rate limits in the constructor for type safety:Dynamic Definition
Define rate limits inline when callinglimit():
When to Use Dynamic Limits
1. One-Off Rate Limits
For rarely-used rate limits that don’t warrant a static definition:2. User-Specific Limits
Different rate limits based on user tier or subscription:3. Configuration from Database
Rate limits stored in your database:4. Time-Based Limits
Different limits during peak vs off-peak hours:5. A/B Testing Rate Limits
Test different rate limit configurations:Type Safety with Dynamic Limits
When using dynamic configs, TypeScript requires the config parameter:client/index.ts:307-322):
Combining Static and Dynamic
You can override static configs with dynamic ones:Pattern: Rate Limit Factory
Create reusable rate limit configurations:Dynamic Limits with React Hooks
You can also use dynamic configs with theuseRateLimit hook:
Best Practices
- Prefer static definitions: Use the constructor for most rate limits
- Document dynamic configs: Comment why a dynamic config is needed
- Validate dynamic configs: Ensure rate/period values are reasonable
- Cache configs: Don’t recalculate on every request if possible
- Consider maintenance: Dynamic configs are harder to audit and update
Validation Example
When NOT to Use Dynamic Limits
Performance Considerations
Dynamic configs have minimal overhead, but:- Database lookups add latency: Fetching configs from the database takes time
- No caching by default: Each request recalculates the config
- Type checking is runtime: TypeScript can’t validate dynamic configs at compile time
For more advanced patterns, see Sharding for high-throughput scenarios and Reservations for preventing starvation.