Strait is a rate-limiting library designed to provide security you don't need to think about. Whenever you have code to protect, put a Strait in front of it.
It strikes an excellent balance between accuracy and memory usage, with a default accuracy of 1/60th of the limit period.
Add this line to your application's Gemfile:
And then execute:
Or install it yourself as:
$ gem install strait
Let's say you have a Rails controller with a lot of DoS attack potential.
class SecureThingController def do_a_scare # Does some heavy work that could open it to a DoS attack! end end
Well dang, that's no good. Anybody could send thousands of requests to this and take your entire site down, right as you're meeting with an important investor!
Let's put a Strait in front of it!
class SecureThingController ScareLimiter = Strait.new('do_a_scare') do limit 5, per: 1.minute end rescue_from Strait::RateLimitExceeded do render :rate_limit_exceeded end def do_a_scare ScareLimiter.limit!(current_user) # Does heavy work, but only if the user hasn't exceeded their rate limit! end end
Viola, just like that, we've got rate limiting. Now a user is limited to 5 per minute!
To understand why Strait isn't perfectly accurate, we should understand how it's implemented. Strait is based on the bucketed-log pattern made popular by Figma, which chooses lower memory usage over perfect accuracy. Despite this decreased accuracy, it fails secure, and should have enough accuracy to not be noticed.
Each rate limiter stores data as a set of N buckets per period. For example, with 10 buckets and a 1-hour period, each bucket covers 6 minutes. To check the limit, we sum all buckets which overlap the last hour. If the buckets are large (like 6 minutes) this can be up to one bucket longer than the period, resulting in a longer block than 100% accuracy.
The default accuracy in Strait is 60 buckets per period. For a 1-hour period, this is up to 1 minute of inaccuracy. For a 1-minute period, it's up to 1-second. For a 1-day period, it's up to 24 minutes. You can adjust this to increase accuracy, but it will also use more memory.
After checking out the repo, run
bin/setup to install dependencies. Then, run
rake spec to run the tests. You can also run
bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run
bundle exec rake install. To release a new version, update the version number in
version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the
.gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/hummingbird-me/strait.
The gem is available as open source under the terms of the Apache-2.0 License.