Hammer.Redis.SlidingWindow (hammer_backend_redis v7.1.0)
View SourceThis module implements the Rate Limiting Sliding Window algorithm.
The sliding window algorithm works by tracking requests within a moving time window. Unlike a fixed window that resets at specific intervals, the sliding window provides a smoother rate limiting experience by considering the most recent window of time.
For example, with a 60 second window:
- At time t, we look back 60 seconds and count all requests in that period
- At time t+1, we look back 60 seconds from t+1, dropping any requests older than that
- This creates a "sliding" effect where the window gradually moves forward in time
The algorithm:
- When a request comes in, we store it with the current timestamp
- To check if rate limit is exceeded, we:
- Count all requests within the last <scale> seconds
- If count <= limit: allow the request
- If count > limit: deny and return time until oldest request expires
- Old entries outside the window are automatically cleaned up
This provides more precise rate limiting compared to fixed windows, avoiding the edge case where a burst of requests spans a fixed window boundary.
The sliding window algorithm is a good choice when:
- You need precise rate limiting without allowing bursts at window boundaries
- Accuracy of the rate limit is critical for your application
- You can accept slightly higher storage overhead compared to fixed windows
- You want to avoid sudden changes in allowed request rates
Common use cases include:
- API rate limiting where consistent request rates are important
- Financial transaction rate limiting
- User action throttling requiring precise control
- Gaming or real-time applications needing smooth rate control
- Security-sensitive rate limiting scenarios
The main advantages over fixed windows are:
- No possibility of 2x burst at window boundaries
- Smoother rate limiting behavior
- More predictable request patterns
The tradeoffs are:
- Slightly more complex implementation
- Higher storage requirements (need to store individual request timestamps)
- More computation required to check limits (need to count requests in window)
For example, with a limit of 100 requests per minute:
- Fixed window might allow 200 requests across a boundary (100 at 11:59, 100 at 12:00)
- Sliding window ensures no more than 100 requests in ANY 60 second period
Example usage:
defmodule MyApp.RateLimit do
use Hammer, backend: Hammer.Redis, algorithm: :sliding_window
end
MyApp.RateLimit.start_link([])
# Allow 10 requests in any 1 second window
MyApp.RateLimit.hit("user_123", 1000, 10)