A Redis module that provides rate limiting in Redis as a single command. Implements the fairly sophisticated generic cell rate algorithm which provides a rolling time window and doesn't depend on a background drip process.
This implementation is based on amazing projects such as:
- throttled: An implementation that can be used standalone or easily plugged into a Go HTTP stack.
- redis-cell: An implementation in Rust that can be loaded from directly within Redis as a module.
- redis-gcra: An implementation that runs in Lua from within Redis and which provides a Ruby API.
While those projects where designed to be modular and flexible this is a straightforward implementation of the GCR algorithm, in 130 lines of C, without any external dependencies.
Clone and build this project from source.
$ git clone https://github.com/onsigntv/redis-rate-limiter.git $ cd redis-rate-limiter $ make $ cp ratelimit.so /path/to/modules/
Run Redis pointing to the newly built module:
redis-server --loadmodule /path/to/modules/ratelimit.so
Alternatively add the following to a
From Redis (try running
redis-cli) use the new
RATER.LIMIT command loaded by
the module. It's used like this:
RATER.LIMIT <key> <max_burst> <count per period> <period> [<quantity>]
key is an identifier to rate limit against. Examples might be:
- A user account's unique identifier.
- The origin IP address of an incoming request.
- A static string (e.g.
global) to limit actions across the entire system.
RATER.LIMIT user123 15 30 60 1 ▲ ▲ ▲ ▲ ▲ | | | | └───── apply 1 token (default if omitted) | | └──┴─────── 30 tokens / 60 seconds | └───────────── 15 max_burst └─────────────────── key "user123"
This means that a single token (the
1 in the last parameter) should be
applied against the rate limit of the key
user123. 30 tokens on the key are
allowed over a 60 second period with a maximum initial burst of 15 tokens. Rate
limiting parameters are provided with every invocation so that limits can
easily be reconfigured on the fly.
The command will respond with an array of integers:
127.0.0.1:6379> RATER.LIMIT user123 15 30 60 1) (integer) 0 2) (integer) 16 3) (integer) 15 4) (integer) -1 5) (integer) 2
The meaning of each array item is:
- Whether the action was limited:
0indicates the action is allowed.
1indicates that the action was limited/blocked.
- The total limit of the key (
max_burst+ 1). This is equivalent to the common
- The remaining limit of the key. Equivalent to
- The number of seconds until the user should retry, and always
-1if the action was allowed. Equivalent to
- The number of seconds until the limit will reset to its maximum capacity.
Multiple Rate Limits
Implement different types of rate limiting by using different key names.
RATER.LIMIT user123-read-rate 15 30 60 RATER.LIMIT user123-write-rate 5 10 60
Peeking The Value of a Key
You can use a quantity of
0 to inspect the current limit of a key without modifying it.
RATER.LIMIT user123 15 30 60 0
This is free software under the terms of MIT the license (see the file
LICENSE for details).