A Redis backend for the Hammer rate-limiter.
This backend is a thin Redix wrapper. A single connection is used per rate-limiter. It should be enough for most use-cases since packets for rate limiting requests are short (i.e. no head of line blocking) and Redis is OK with pipelining (i.e. we don't block awaiting replies). Consider benchmarking before introducing more connections since TCP performance might be unintuitive. For possible pooling approaches, see Redix docs on pooling and also PartitionSupervisor. Do not use poolboy or db_connection-like pools since they practically disable pipelining which leads to worse connection utilisation and worse performance.
The algorithm we are using is the first method described (called "bucketing") in Rate Limiting with Redis. In other sources it's sometimes called a "fixed window counter".
TODO: document ttl issues if servers are misconfigured
Hammer-backend-redis
is available in Hex, the package
can be installed by adding hammer_backend_redis
to your list of dependencies in mix.exs
:
def deps do
[
{:hammer_backend_redis, "~> 7.0"}
]
end
Define the rate limiter:
defmodule MyApp.RateLimit do
use Hammer, backend: Hammer.Redis
end
And add it to your app's supervision tree:
children = [
{MyApp.RateLimit, url: "redis://localhost:6379"}
]
And that's it, calls to MyApp.RateLimit.hit/3
and so on will use Redis to store
the rate-limit counters. See the documentation for more details.
You need a running Redis instance. One can be started locally using docker compose up -d redis
.
See the compose.yml for more details.
If you're having trouble, open an issue on this repo.