Skip to content
/ redis-gcra Public

Redis-backed rate limiting based on generic cell rate algorithm

License

Notifications You must be signed in to change notification settings

rwz/redis-gcra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RedisGCRA

Build Status Gem Version

This gem is an implementation of GCRA for rate limiting based on Redis. The code requires Redis version 3.2 or newer since it relies on replicate_commands feature.

Installation

gem "redis-gcra"

And then execute:

$ bundle

Or install it yourself as:

$ gem install redis-gcra

Usage

In order to perform rate limiting, you need to call the limit method.

In this example the rate limit bucket has 1000 tokens in it and recovers at speed of 100 tokens per minute.

redis = Redis.new

result = RedisGCRA.limit(
  redis: redis,
  key: "overall-account/bob@example.com",
  burst: 1000,
  rate: 100,
  period: 60, # seconds
  cost: 2
)

result.limited?    # => false - request should not be limited
result.remaining   # => 998   - remaining number of requests until limited
result.retry_after # => nil   - can retry without delay
result.reset_after # => ~0.6  - in 0.6 seconds rate limiter will completely reset

# call limit 499 more times in rapid succession and you get:

result.limited?    # => true  - request should be limited
result.remaining   # => 0     - no requests can be made at this point
result.retry_after # => ~1.2  - can retry in 1.2 seconds
result.reset_after # => ~600  - in 600 seconds rate limiter will completely reset

The implementation utilizes single key in Redis that matches the key you pass to the limit method. If you need to reset rate limiter for particular key, just delete the key from Redis:

# Let's imagine `overall-account/bob@example.com` is limited.
# This will effectively reset limit for the key:
redis.del "overall-account/bob@example.com"

You call also retrieve the current state of rate limiter for particular key without actually modifying the state. In order to do that, use the peek method:

result = RedisGCRA.peek(
  redis: redis,
  key: "overall-account/bob@example.com",
  burst: 1000,
  rate: 100,
  period: 60 # seconds
)

result.limited?    # => true  - current state is limited
result.remaining   # => 0     - no requests can be made
result.retry_after # => ~0.6  - in 0.6 seconds remaining will become 1
result.reset_after # => ~600  - in 600 seconds rate limiter will completely reset

Inspiration

This code was inspired by this great blog post by Brandur Leach and his amazing work on throttled Go package.

License

The gem is available as open source under the terms of the MIT License.

About

Redis-backed rate limiting based on generic cell rate algorithm

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages