{"id":18762575,"url":"https://github.com/hummingbird-me/strait","last_synced_at":"2025-04-13T03:32:18.233Z","repository":{"id":35072509,"uuid":"196792345","full_name":"hummingbird-me/strait","owner":"hummingbird-me","description":"🏴‍☠️  Rate-limiting code to defend your nation-state from pillagers","archived":false,"fork":false,"pushed_at":"2023-01-28T01:01:04.000Z","size":103,"stargazers_count":13,"open_issues_count":6,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-26T21:38:09.140Z","etag":null,"topics":["gem","rails","rate-limiting","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hummingbird-me.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-14T04:12:12.000Z","updated_at":"2024-03-18T08:24:55.000Z","dependencies_parsed_at":"2023-02-15T13:46:01.262Z","dependency_job_id":null,"html_url":"https://github.com/hummingbird-me/strait","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hummingbird-me%2Fstrait","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hummingbird-me%2Fstrait/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hummingbird-me%2Fstrait/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hummingbird-me%2Fstrait/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hummingbird-me","download_url":"https://codeload.github.com/hummingbird-me/strait/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248516908,"owners_count":21117347,"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":["gem","rails","rate-limiting","ruby"],"created_at":"2024-11-07T18:22:05.819Z","updated_at":"2025-04-13T03:32:17.977Z","avatar_url":"https://github.com/hummingbird-me.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Strait\n\n[![Coverage][shield-coverage]][coverage]\n[![Maintainability][shield-maintainability]][maintainability]\n[![Github Actions][shield-actions]][actions]\n[![Rubygem Version][shield-version]][version]\n\n[shield-coverage]: https://img.shields.io/codeclimate/coverage/hummingbird-me/strait.svg?logo=code-climate\u0026style=for-the-badge\n[coverage]: https://codeclimate.com/github/hummingbird-me/strait/progress/coverage\n[shield-maintainability]: https://img.shields.io/codeclimate/maintainability/hummingbird-me/strait.svg?logo=code-climate\u0026style=for-the-badge\n[maintainability]: https://codeclimate.com/github/hummingbird-me/strait/progress/maintainability\n[shield-actions]: https://img.shields.io/github/checks-status/hummingbird-me/strait/main?style=for-the-badge\n[actions]: https://github.com/hummingbird-me/strait/actions\n[shield-version]: https://img.shields.io/gem/v/strait?label=%20\u0026logo=rubygems\u0026logoColor=white\u0026style=for-the-badge\n[version]: https://rubygems.org/gems/strait\n\nStrait 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.\n\nIt strikes an excellent balance between accuracy and memory usage, with a default accuracy of 1/60th of the limit period.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'strait'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install strait\n\n## Usage\n\nLet's say you have a Rails controller with a lot of DoS attack potential.\n\n```ruby\nclass SecureThingController\n  def do_a_scare\n    # Does some heavy work that could open it to a DoS attack!\n  end\nend\n```\n\nWell 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!\n\nLet's put a Strait in front of it!\n\n```ruby\nclass SecureThingController\n  ScareLimiter = Strait.new('do_a_scare') do\n    limit 5, per: 1.minute\n  end\n\n  rescue_from Strait::RateLimitExceeded do\n    render :rate_limit_exceeded\n  end\n\n  def do_a_scare\n    ScareLimiter.limit!(current_user)\n    # Does heavy work, but only if the user hasn't exceeded their rate limit!\n  end\nend\n```\n\nViola, just like that, we've got rate limiting. Now a user is limited to 5 per minute!\n\n## Accuracy\n\nTo 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][figma-post], which chooses lower memory usage over perfect accuracy. Despite this decreased accuracy, it fails secure, and should have enough accuracy to not be noticed.\n\nEach 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.\n\nThe 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.\n\n[figma-post]: https://www.figma.com/blog/an-alternative-approach-to-rate-limiting/\n\n## Development\n\nAfter 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.\n\nTo 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](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/hummingbird-me/strait.\n\n## License\n\nThe gem is available as open source under the terms of the [Apache-2.0 License](https://opensource.org/licenses/Apache-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhummingbird-me%2Fstrait","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhummingbird-me%2Fstrait","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhummingbird-me%2Fstrait/lists"}