rate_limiter v1.0.0

GitHub release Build Status License


This shard provides a Crystal implementation of the token bucket algorithm for rate limiting. You can check out the API documentation here.


1 - Add the dependency to your shard.yml:

    github: lbarasti/rate_limiter

2 - Run shards install


Remember to import the shard at the top of your file.

require "rate_limiter"

Now you can initialise a rate limiter that produces 1 token every few seconds

rl = RateLimiter.new(interval: 3.seconds)

Mind that the first call to #get will return immediately, as buckets are initialised with 1 token, by default.

rl.get # => #<RateLimiter::Token:0x7f9c55458f00 @created_at=...>

The next call to #get will block for approx. 3 seconds

start_time = Time.utc
Time.utc - start_time # => 00:00:03.000426843

We can also provide a max_wait parameter to #get.


This call will block for at most 0.5 seconds. If a token is not returned within that interval, then a RateLimiter::Timeout is returned.

Rate limiters also expose non-blocking methods.

rl.get? # returns `nil` if no token is available

rl.get! # raises a RateLimiter::Timeout exception if no token is available

You can pass #get! a max_wait parameter.


This will raise a RateLimiter::Timeout exception if no token is returned within a 1 second interval.

Burst size

You can define a rate limiter that accumulates unused tokens up to the specified value by providing a max_burst parameter to RateLimiter.new - the default is 1.

RateLimiter.new(rate: 0.5, max_burst: 10)

This will generate 1 token every 2 seconds and store up to 10 unused tokens for later use. See Wikipedia's Burst size for more details.

Under the hood

Why do I need a rate limiter?

  • We're calling an API that throttles us when we call it too frequently, and we'd rather avoid that.
  • We are exposing an API to customers and want to ensure we don't get flooded with requests. For example, we might want to rate limit calls by client id, so that one misbehaving client will not affect the others.
  • One of our ETL stages talks to a datastore that limits the number of requests per second we can send.
  • We have to run a database migration in production and we don't want to affect the responsiveness of the service.


Run the following to run the tests.

crystal spec


  1. Fork it (https://github.com/lbarasti/rate_limiter/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request


github statistic
  • 4
  • 0
  • 0
  • 0
  • 5 days ago
  • November 21, 2020

MIT License

Synced at

Thu, 26 Nov 2020 19:36:53 GMT