{"id":13647762,"url":"https://github.com/brandur/redis-cell","last_synced_at":"2025-05-14T04:09:01.150Z","repository":{"id":42225575,"uuid":"72307650","full_name":"brandur/redis-cell","owner":"brandur","description":"A Redis module that provides rate limiting in Redis as a single command.","archived":false,"fork":false,"pushed_at":"2025-01-16T18:48:15.000Z","size":245,"stargazers_count":1214,"open_issues_count":11,"forks_count":69,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-11T16:05:18.508Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brandur.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-10-29T20:27:06.000Z","updated_at":"2025-04-27T09:15:11.000Z","dependencies_parsed_at":"2024-01-14T10:15:47.330Z","dependency_job_id":"d0e7c7ac-7e86-4528-b62d-44686709794e","html_url":"https://github.com/brandur/redis-cell","commit_stats":{"total_commits":103,"total_committers":9,"mean_commits":"11.444444444444445","dds":0.5145631067961165,"last_synced_commit":"bada85d5df0908a8372b4081845ef464a5702125"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fredis-cell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fredis-cell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fredis-cell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandur%2Fredis-cell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brandur","download_url":"https://codeload.github.com/brandur/redis-cell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254070012,"owners_count":22009558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:03:45.720Z","updated_at":"2025-05-14T04:08:56.091Z","avatar_url":"https://github.com/brandur.png","language":"Rust","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# redis-cell [![Build Status](https://github.com/brandur/redis-cell/workflows/redis-cell%20CI/badge.svg)](https://github.com/brandur/redis-cell/actions)\n\n**Warning:** This package is in \"best effort\" maintenance mode. I try to\nrespond to opened issues and keep it reasonably up-to-date with respect to the\nunderlying Rust toolchain, but am no longer actively developing it.\n\nA Redis module that provides rate limiting in Redis as a single command.\nImplements the fairly sophisticated [generic cell rate algorithm][gcra] (GCRA)\nwhich provides a rolling time window and doesn't depend on a background drip\nprocess.\n\nThe primitives exposed by Redis are perfect for doing work around rate\nlimiting, but because it's not built in, it's very common for companies and\norganizations to implement their own rate limiting logic on top of Redis using\na mixture of basic commands and Lua scripts (I've seen this at both Heroku and\nStripe for example). This can often result in naive implementations that take a\nfew tries to get right. The directive of redis-cell is to provide a\nlanguage-agnostic rate limiter that's easily pluggable into many cloud\narchitectures.\n\n[Informal benchmarks][benchmarks] show that redis-cell is pretty fast, taking a\nlittle under twice as long to run as a basic Redis `SET` (very roughly 0.1 ms\nper command as seen from a Redis client).\n\n## Install\n\n[Binaries for redis-cell are available for Mac and Linux][releases]. Open\nan issue if there's interest in having binaries for architectures or operating\nsystems that are not currently supported.\n\nDownload and extract the library, then move it somewhere that Redis can access\nit (note that the extension will be **.dylib** instead of **.so** for Mac\nreleases):\n\n```\n$ tar -zxf redis-cell-*.tar.gz\n$ cp libredis_cell.so /path/to/modules/\n```\n\n**Or**, clone and build the project from source. You'll need to [install\nRust][rust-downloads] to do so (this may be as easy as a `brew install rust` if\nyou're on Mac).\n\n```\n$ git clone https://github.com/brandur/redis-cell.git\n$ cd redis-cell\n$ cargo build --release\n$ cp target/release/libredis_cell.dylib /path/to/modules/\n```\n\n**Note that Rust 1.13.0+ is required.**\n\nRun Redis pointing to the newly built module:\n\n```\nredis-server --loadmodule /path/to/modules/libredis_cell.so\n```\n\nAlternatively add the following to a `redis.conf` file:\n\n```\nloadmodule /path/to/modules/libredis_cell.so\n```\n\n## Usage\n\nFrom Redis (try running `redis-cli`) use the new `CL.THROTTLE` command loaded by\nthe module. It's used like this:\n\n```\nCL.THROTTLE \u003ckey\u003e \u003cmax_burst\u003e \u003ccount per period\u003e \u003cperiod\u003e [\u003cquantity\u003e]\n```\n\nWhere `key` is an identifier to rate limit against. Examples might be:\n\n* A user account's unique identifier.\n* The origin IP address of an incoming request.\n* A static string (e.g. `global`) to limit actions across the entire system.\n\nFor example:\n\n```\nCL.THROTTLE user123 15 30 60 1\n               ▲     ▲  ▲  ▲ ▲\n               |     |  |  | └───── apply 1 token (default if omitted)\n               |     |  └──┴─────── 30 tokens / 60 seconds\n               |     └───────────── 15 max_burst\n               └─────────────────── key \"user123\"\n```\n\n### Response\n\nThis means that a single token (the `1` in the last parameter) should be\napplied against the rate limit of the key `user123`. 30 tokens on the key are\nallowed over a 60 second period with a maximum initial burst of 15 tokens. Rate\nlimiting parameters are provided with every invocation so that limits can\neasily be reconfigured on the fly.\n\nThe command will respond with an array of integers:\n\n```\n127.0.0.1:6379\u003e CL.THROTTLE user123 15 30 60\n1) (integer) 0\n2) (integer) 16\n3) (integer) 15\n4) (integer) -1\n5) (integer) 2\n```\n\nThe meaning of each array item is:\n\n1. Whether the action was limited:\n    * `0` indicates the action is allowed.\n    * `1` indicates that the action was limited/blocked.\n2. The total limit of the key (`max_burst` + 1). This is equivalent to the\n   common `X-RateLimit-Limit` HTTP header.\n3. The remaining limit of the key. Equivalent to `X-RateLimit-Remaining`.\n4. The number of seconds until the user should retry, and always `-1` if the\n   action was allowed. Equivalent to `Retry-After`.\n5. The number of seconds until the limit will reset to its maximum capacity.\n   Equivalent to `X-RateLimit-Reset`.\n\n### Multiple Rate Limits\n\nImplement different types of rate limiting by using different key names:\n\n```\nCL.THROTTLE user123-read-rate 15 30 60\nCL.THROTTLE user123-write-rate 5 10 60\n```\n\n## On Rust\n\nredis-cell is written in Rust and uses the language's FFI module to interact\nwith [Redis' own module system][redis-modules]. Rust makes a very good fit here\nbecause it doesn't need a GC and is bootstrapped with only a tiny runtime.\n\nThe author of this library is of the opinion that writing modules in Rust\ninstead of C will convey similar performance characteristics, but result in an\nimplementation that's more likely to be devoid of the bugs and memory pitfalls\ncommonly found in many C programs.\n\n## License\n\nThis is free software under the terms of MIT the license (see the file\n`LICENSE` for details).\n\n## Development\n\n### Tests and checks\n\nRun the test suite:\n\n    cargo test\n\n    # specific test\n    cargo test it_rates_limits\n\n    # with debug output on stdout\n    cargo test it_rates_limits -- --nocapture\n\nCI has checks for both [Rustfmt][rustfmt] and [Clippy][clippy] (Rust's linter).\nThese can be installed and run locally using Rustup's component framework:\n\n    rustup component add rustfmt\n    cargo fmt --all\n\n    rustup component add clippy\n    cargo clippy -- -D warnings\n\n### Releasing\n\nReleases are performed automatically from a script in CI which activates when a\nnew tag of the format `v1.2.3` is released. The script builds binaries for all\ntarget systems and uploads them to GitHub's [releases][releases] page.\n\nTo perform a release:\n\n1. Add a changelog entry in `CHANGELOG.md` using the existing format.\n2. Bump the version number in `Cargo.toml`.\n3. Commit these changes with a message like `Bump to version 1.2.3`.\n4. Tag the release with `git tag v1.2.3` (make sure to include a leading `v`).\n5. `ggpush --tags`\n6. Edit the new release's title and body in [GitHub][releases] (a human touch\n   is still expected for the final product). Use the contents for the new\n   version from `CHANGELOG.md` as the release's body, which allows Markdown\n   content.\n\n[benchmarks]: https://gist.github.com/brandur/90698498bd543598d00df46e32be3268\n[clippy]: https://github.com/rust-lang/rust-clippy\n[gcra]: https://en.wikipedia.org/wiki/Generic_cell_rate_algorithm\n[redis-modules]: https://github.com/redis/redis-doc/blob/master/docs/reference/modules/_index.md\n[releases]: https://github.com/brandur/redis-cell/releases\n[rust-downloads]: https://www.rust-lang.org/en-US/downloads.html\n[rustfmt]: https://github.com/rust-lang/rustfmt\n\n\u003c!--\n# vim: set tw=79:\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandur%2Fredis-cell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrandur%2Fredis-cell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandur%2Fredis-cell/lists"}