Rate Limits
Requests per second
Rate limits in Trypema are expressed as requests per second using the RateLimit type. This wraps a positive f64, so non-integer rates are fully supported:
use trypema::RateLimit;
// Integer rate: 10 requests per second
let rate = RateLimit::try_from(10.0).unwrap();
assert_eq!(*rate, 10.0);
// Non-integer rate: 0.5 requests per second (one request every 2 seconds)
let slow_rate = RateLimit::try_from(0.5).unwrap();
assert_eq!(*slow_rate, 0.5);
// Non-integer rate: 5.5 requests per second
let fractional = RateLimit::try_from(5.5).unwrap();
assert_eq!(*fractional, 5.5);
// Invalid: must be greater than 0
assert!(RateLimit::try_from(0.0).is_err());
assert!(RateLimit::try_from(-1.0).is_err());
Window capacity
The rate limit alone does not determine how many requests are allowed. Trypema uses a sliding time window (see Sliding Windows), and the actual capacity is:
window_capacity = window_size_seconds * rate_limit
Example: With a 60-second window and a rate limit of 5.0 req/s:
- Window capacity = 60 * 5.0 = 300 requests
This means: at any point in time, the limiter looks at the last 60 seconds of activity. If fewer than 300 requests have been recorded in that window, the next request is allowed.
More examples
rate_limit | window_size_seconds | Window capacity |
|---|---|---|
| 10.0 | 60 | 600 requests |
| 0.5 | 60 | 30 requests |
| 100.0 | 10 | 1000 requests |
| 5.5 | 120 | 660 requests |
u64). For non-integer rates, the effective capacity is computed using floating-point multiplication and then compared against integer counters, so you should treat the limit as approximate at the edges.Sticky rate limits
The first inc() call for a key stores the rate limit for that key's lifetime in the limiter. Subsequent calls for the same key ignore the rate_limit argument and use the stored value.
This prevents races where concurrent callers might specify different limits for the same key. If you need to change a key's rate limit, let the old entry expire (or be cleaned up by the cleanup loop) and start fresh.
Unlimited rate (for testing)
If you want to track behaviour without enforcing limits (e.g., in tests), use RateLimit::max():
use trypema::RateLimit;
let unlimited = RateLimit::max();
assert_eq!(*unlimited, f64::MAX);
This creates a rate limit so large that no key will ever hit it in practice.
Next steps
- Sliding Windows -- how the time window and bucket coalescing work
- Decisions -- what the limiter returns for each request

