Home

Awesome

Hammer.Redis

Build Status Hex.pm Documentation Total Download License

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

Installation

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

Usage

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.

Run tests locally

You need a running Redis instance. One can be started locally using docker compose up -d redis. See the compose.yml for more details.

Getting Help

If you're having trouble, open an issue on this repo.