Gem Version CI Code Quality Coverage Status Online docs

Rollie is a multi-purpose, fast, Redis backed rate limiter that can be used to limit requests to external APIs, in Rack middleware, etc. Rollie uses a dedicated Redis connection pool implemented using connection_pool for more efficient Redis connection management. The Redis algorithm was inspired by the rolling-rate-limiter node package.

The key implementation detail is that Rollie utilizes a rolling window to bucket invocations in. Meaning, if you set a limit of 100 per 30 seconds, Rollie will start the clock in instant it is first executed with a given key.

For example, first execution:

rollie ="api", limit: 10, interval: 30000)
rollie.within_limit do
# => 2016-12-03 08:31:23.873

This doesn't mean the count is reset back to 0 at 2016-12-03 08:31:53.873. Its a continuous rolling count, the count is checked with every invocation over the last 30 seconds.

If you invoke this rate 9 times at 2016-12-03 08:31:53.500, you will only be able to make one more call until 2016-12-03 08:32:23.500.


Add it to your Gemfile:

gem 'rollie'

Or install it manually:

gem install rollie


Rollie is simple to use and has only one method, within_limit. within_limit expects a block and that block will be executed only if you are within the limit.

Initialize Rollie with a key used to uniquely identify what you are limiting. Use the options to set the limit and interval in milliseconds.

# limit 30 requests per second.
twitter_rate ="twitter_requests", limit: 30, interval: 1000)
status = twitter_rate.within_limit do

The status will tell you the current state. You can also see the current count and how long until the bucket resets.

# => false
# => 1
# => 987 # milliseconds

Once exceeded:

# => true
# => 30
# => 461 # milliseconds

You can also use a namespace if you want to track multiple entities, for example users.
  namespace: "user_messages",
  limit: 100,
  interval: 30000

Counting blocked actions

By default, blocked actions are not counted against the callee. This allows for the block to be executed within the rate even when there is a continuous flood of action. If you wish to change this behaviour, for example to require the callee to back off before being allowed to execute again, set this option to true.

request_rate =
  namespace: "ip",
  limit: 30,
  interval: 1000,
  count_blocked: true


By default Rollie will try to connect to Redis using ENV["REDIS_URL"] if set or fallback to localhost:6379. You can set an alternate Redis configuration:

Rollie.redis = {
    url: CONFIG[:redis_url],
    pool_size: 5,
    pool_timeout: 1,
    driver: :hiredis

If using rails, create an initializer config/initializers/rollie.rb with these settings.