View Source Hammer.ETS.SlidingWindow (hammer v7.0.0-rc.3)
This 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
The sliding window algorithm supports the following options:
:clean_period
- How often to run the cleanup process (in milliseconds) Defaults to 1 minute. The cleanup process removes expired window entries.
Example configuration:
MyApp.RateLimit.start_link(
clean_period: :timer.minutes(5),
)
This would run cleanup every 5 minutes and clean up old windows.
Summary
Functions
Cleans up all of the old entries from the table based on the key_older_than
option.
Returns the count of requests for a given key
Checks if a key is allowed to perform an action based on the sliding window algorithm.
Functions
@spec clean(config :: Hammer.ETS.config()) :: non_neg_integer()
Cleans up all of the old entries from the table based on the key_older_than
option.
@spec get(table :: atom(), key :: String.t(), scale :: pos_integer()) :: non_neg_integer()
Returns the count of requests for a given key
@spec hit( table :: atom(), key :: String.t(), scale :: pos_integer(), limit :: pos_integer() ) :: {:allow, non_neg_integer()} | {:deny, non_neg_integer()}
Checks if a key is allowed to perform an action based on the sliding window algorithm.