CLI tool
brandur/redis-cell avatar
brandur/redis-cell

redis-cell puts rate limiting in one command, in maintenance mode

A Redis module that provides rate limiting in Redis as a single command.

1,261 stars77 forksCMIT

At a glance

What is it?
redis-cell is a Redis module implementing GCRA, a generic cell rate algorithm that gives a rolling window without needing a background process to drip tokens. The command returns five integers that map directly onto the X-RateLimit headers, and the repository now carries an explicit best effort maintenance notice and Valkey support.
Who is it for?
Adopt redis-cell if you run Redis or Valkey and want rate limiting that does not depend on application-side Lua or a token bucket service, and you are content to own it from here. Do not adopt it expecting an actively developed project, because the README states it is in best effort maintenance mode with no active development.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 45 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem it solves

The argument in the README is about the DIY alternative. The primitives Redis exposes are well suited to rate limiting work, but because it is not built in, it is very common for companies and organisations to implement their own rate limiting logic on top of Redis using a mixture of basic commands and Lua scripts. The author says he has seen this at both Heroku and Stripe.

The complaint is not that the approach is unusual, it is that it usually takes several tries to get right, and the result is often a naive implementation.

redis-cell's directive is a language-agnostic rate limiter that plugs easily into many cloud architectures. Language-agnostic matters here: the rate limiting happens inside Redis, so a Python service, a Go service and a Ruby service all get the same behaviour without sharing code, and without three Lua scripts that drift apart.

The algorithm is GCRA, the generic cell rate algorithm, which provides a rolling time window and does not depend on a background drip process. That last property is the interesting design choice. Token bucket implementations that refill on a timer need something to refill them; GCRA derives the current state from a stored theoretical arrival time, so a single key holds the whole state and there is nothing to schedule.

The command and its five integers

The module loads a single command, `CL.THROTTLE`, with this shape:

code
CL.THROTTLE <key> <max_burst> <count per period> <period> [<quantity>]

The README works through a concrete example, `CL.THROTTLE user123 15 30 60 1`, annotated to show that one token is applied against a limit of 30 tokens per 60 seconds with a maximum initial burst of 15. The key is an identifier to rate limit against, and the suggested values are a user account's unique identifier, the origin IP address of an incoming request, or a static string such as `global` to limit actions across the whole system.

The quantity parameter defaults to one token when omitted. And the limits are provided on every invocation rather than configured server-side, which the README presents as the reason limits can be reconfigured on the fly.

The response is an array of five integers, and the documentation maps each one onto the HTTP header an API would want:

1. Whether the action was limited, `0` allowed or `1` blocked. 2. The total limit of the key, `max_burst` plus one, equivalent to `X-RateLimit-Limit`. 3. The remaining limit, equivalent to `X-RateLimit-Remaining`. 4. Seconds until the user should retry, always `-1` if the action was allowed, equivalent to `Retry-After`. 5. Seconds until the limit resets to maximum capacity, equivalent to `X-RateLimit-Reset`.

That mapping is the part to design around. An API gateway can pass those five values straight into response headers without interpreting them, which means the semantics live in one place.

Multiple limits are done with different key names rather than with configuration, so a read limit and a write limit are two keys against the same identifier.

Installation and loading the module

Binaries are available for Mac and Linux, and the README asks for an issue if there is interest in other architectures. Unpacking and copying the shared library into a directory Redis can reach is the whole install, with the note that the extension is a `.dylib` on Mac rather than a `.so`.

Building from source needs Rust, and the README notes the required version as Rust 1.13.0 or later:

bash
git clone https://github.com/brandur/redis-cell.git
cd redis-cell
cargo build --release

The module is then loaded either on the command line:

bash
redis-server --loadmodule /path/to/modules/libredis_cell.so

or with a `loadmodule` line in `redis.conf`. Both forms are given because the first is what you do in a container command and the second is what goes in configuration management.

The Cargo configuration confirms what the artifact is: `crate-type = ["dylib"]`, since a Redis module is loaded as a dynamic library. The runtime dependencies are three and all small: `bitflags` for option bitmasks, `libc` for the FFI layer, and `time` with the formatting feature. The build dependency is `cc`, because the FFI is against Redis' own C module API through the header in `include/`.

The crate is edition 2024 and the package version is 0.5.0.

Why Rust, stated as an opinion

The README says redis-cell is written in Rust and uses the language's FFI module to interact with Redis' own module system, and argues that Rust is a good fit because it does not need a GC and is bootstrapped with only a tiny runtime.

Then it says something more revealing: the author is of the opinion that writing modules in Rust instead of C will convey similar performance characteristics, but result in an implementation more likely to be devoid of the bugs and memory pitfalls commonly found in many C programs.

That is a claim about the class of failure a memory-safe language removes, which is the right argument for a module that parses arguments supplied by arbitrary clients and runs inside the database process. A module-level memory bug is a server-level memory bug.

On performance the README is careful not to overclaim, describing informal benchmarks showing redis-cell taking a little under twice as long to run as a basic Redis `SET`, very roughly 0.1 ms per command as seen from a Redis client.

The phrase informal benchmarks is doing real work there. It is not a reproducible number and should not be quoted as a capacity figure, but it does establish the order of magnitude: rate limiting is roughly one command, not a round trip through your application.

Maintenance mode, Valkey, and what to check

The first thing in the README is a warning, and it should be read before anything else. The package is in best effort maintenance mode: the author tries to respond to opened issues and keep it reasonably up to date with respect to the underlying Rust toolchain, but is no longer actively developing it.

That is the defining fact for an adoption decision. There is no deprecation notice and no successor named, so the module does what it did and you own it from here. The release history supports that reading: v0.5.0 on 2025-11-24, v0.4.0 in September 2024, v0.3.1 in June 2023, and the last push on 2026-09-07.

The interesting development in the repository is Valkey support rather than new features. There is a `valkey` Cargo feature, a `valkey.Dockerfile` alongside `redis.Dockerfile`, and separate end-to-end test targets:

bash
make images && make test/e2e

with `test/e2e/redis` and `test/e2e/valkey` running the same suite against both servers. The unit test target also runs the ignored tests single-threaded, which is the pattern for tests that need a live server. Those end-to-end tests use testcontainers with reusable containers, which is why the README explains the `DOCKER_HOST` variable requirement for custom runtimes such as Colima, citing the bollard crate underneath testcontainers.

Quality gates are Rustfmt and Clippy with `-D warnings`, both run in CI and available locally through rustup components. Releases are automated from a CI script triggered by a `v1.2.3` style tag, which builds binaries for all target systems and uploads them to GitHub releases, though the README notes a human still edits the release title and body at the end.

The licence is MIT.

Editorial conclusion

Adopt redis-cell if you run Redis or Valkey and want rate limiting that does not depend on application-side Lua or a token bucket service, and you are content to own it from here. Do not adopt it expecting an actively developed project, because the README states it is in best effort maintenance mode with no active development. Verify first that your Redis or Valkey version loads the module, that the response fields match what your client expects, and that a maintenance-mode module with a last release in November 2025 fits your upgrade plans.

Frequently asked questions

What does redis-cell add to Redis?

A single CL.THROTTLE command implementing the generic cell rate algorithm (GCRA), which gives a rolling time window without needing a background drip process. The response returns five integers covering whether the action was limited, the total limit, the remaining limit, retry-after seconds and reset seconds.

Is redis-cell still actively developed?

No. The README states the package is in best effort maintenance mode, with the author responding to issues and keeping it reasonably up to date against the Rust toolchain, but no longer actively developing it. The newest release is v0.5.0 from 2025-11-24.

How do I install and load redis-cell?

Unpack the release archive and copy the shared library into a directory Redis can reach, a .dylib on Mac, then load it with `redis-server --loadmodule /path/to/modules/libredis_cell.so` or a `loadmodule` line in redis.conf. Building from source needs Rust and `cargo build --release`.

Does redis-cell work with Valkey?

Yes. There is a `valkey` Cargo feature, a separate valkey.Dockerfile, and end-to-end test targets `test/e2e/redis` and `test/e2e/valkey` that run the same suite against both servers via `make images && make test/e2e`.

Official sources

  1. brandur/redis-cell on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/brandur-redis-cell.svg)](https://hysenlabs.com/projects/brandur-redis-cell)

Was this useful?