Rate Limiter
The rate limiter is responsible for limiting the rate of requests a user can make to the application within a given time period. This is useful for preventing a user from spamming the application, but mainly to control the amount of requests a user is allowed to make. The rate limiter is configured in the etc/config/security.yaml file.
Rate limits are measured using a token bucket algorithm. The limit is the maximum number of tokens that can be stored in the bucket. The period is the time in seconds that the bucket is allowed to hold tokens. The strategy is the algorithm used to determine the number of tokens that are added to the bucket.
Default Rate Limiter#
The default rate limiter limits all incoming requests as configured. The Swift\Security\RateLimiter\Kernel\Middleware\RateLimitingMiddleware middleware is responsible for adding the default rate limiter to the request. The default_limit, default_period and default_strategy are configured in the etc/config/security.yaml file. Default rate limiter is disabled by default. To enable it, set default_enabled: true in the rate_limit section. 
By default, each request consumes one token.
GraphQL Rate Limiter#
GraphQl requests consume at least one token, however this is calculated based on the complexity of the query. The complexity of the query is determined by the number of fields in the query divided by 100. For example, a query with 100 fields will consume 1 token. A query with 200 fields will consume 2 tokens. The minimum is 1 token. A query with 170 fields, will consume 2 tokens (170 / 100 = 1.7). This will round off at 2 tokens.
Custom Rate Limiter#
There's a dozen of reasons to use a custom rate limiter. The most common is to limit the rate of requests to a specific endpoint, or you might want to limit the rate of requests to a specific user. You can still combine this with the default rate limiter. An example of this is Login throttling.
Configuration#
The easiest way to configure a custom rate limiter is to add a new rate to the rates array in the rate_limit section of the etc/config/security.yaml file.
The RateLimiterFactory will now look for a rate with the name foo_bar and return a RateLimiter configured as such. 
Rate Limiter Configuration Factory#
The RateLimiterConfigurationFactory is responsible for creating RateLimiterConfigurationInterface instances. These represent the configuration for a rate limiter.
Example#
This example shows how Swift uses the RateLimiterConfigurationFactory to create a RateLimiterConfigurationInterface instance for the custom configured rate limiter through configuration.
Rate Limiter Factory#
The RateLimiterFactory is responsible for creating RateLimiterInterface instances based on the RateLimiterConfigurationInterface.
Example#
This example shows how Swift uses the RateLimiterFactory to create a RateLimiterInterface instance.
Token storage#
The TokenStorage is responsible for storing and fetching token buckets. By default, the TokenStorage is a DatabaseTokenStorage, but a custom TokenStorage can be used.
Example#
Strategy#
The Strategy is responsible for calculating the number of tokens to consume. The default strategy is the SlidingWindowStrategy. A custom strategy can be used by implementing the Swift\Security\RateLimiter\RateLimiterInterface. And defining a factory for initializing the strategy, like the CoreStrategyFactory above.
Strategy#
Strategies are responsible for calculating the number of tokens over a period of time. The default strategy is the SlidingWindowStrategy. This is the strategy that Swift uses by default and is the most common strategy. However, you can create your own strategy and use it by implementing the Swift\Security\RateLimiter\RateLimiterInterface. An example of another strategy is the FixedWindowStrategy.
Sliding window#
The SlidingWindowStrategy calculated the number of available tokens based on how many tokens were consumed between the moment of the request and the moment of the request minus the interval.
For example, if a request is made at time t and the interval is 1 minute. The strategy will fetch all tokens created between t - 1 minute and t. It will now withdraw those tokens from the limit and return the number of tokens that can still be consumed.
Usage#
Interaction with the Rate Limiter is done through the Swift\Security\RateLimiter\RateLimiterFactory. The RateLimiterFactory is responsible for creating RateLimiterInterface instances.
Example of usage in middleware#
Example of usage in EventSubscriber#
Rate Limiter HTTP Headers#
It is good practice to add the rate limiter headers to the response. This is easily done by using the RateLimiter::bindToResponse method. Like in the example above, the RateLimiter::bindToResponse method will add the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers to the response.