{"id":13879586,"url":"https://github.com/coinbase/traffic_jam","last_synced_at":"2025-07-16T15:32:39.285Z","repository":{"id":59157912,"uuid":"30375868","full_name":"coinbase/traffic_jam","owner":"coinbase","description":"DEPRECATED — Ruby library for time-based rate limiting","archived":true,"fork":false,"pushed_at":"2019-10-10T22:14:17.000Z","size":70,"stargazers_count":130,"open_issues_count":0,"forks_count":20,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-10-31T13:54:59.509Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coinbase.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":"2015-02-05T20:10:10.000Z","updated_at":"2024-09-29T01:06:02.000Z","dependencies_parsed_at":"2022-09-13T20:11:27.787Z","dependency_job_id":null,"html_url":"https://github.com/coinbase/traffic_jam","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Ftraffic_jam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Ftraffic_jam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Ftraffic_jam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coinbase%2Ftraffic_jam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coinbase","download_url":"https://codeload.github.com/coinbase/traffic_jam/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226143895,"owners_count":17580245,"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":[],"created_at":"2024-08-06T08:02:25.987Z","updated_at":"2024-11-24T08:31:30.798Z","avatar_url":"https://github.com/coinbase.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# TrafficJam\n\n[![Build Status](https://travis-ci.org/coinbase/traffic_jam.svg?branch=master)](https://travis-ci.org/coinbase/traffic_jam)\n[![Coverage Status](https://coveralls.io/repos/coinbase/traffic_jam/badge.svg?branch=master)](https://coveralls.io/r/coinbase/traffic_jam?branch=master)\n\nThis is a library for enforcing rate limits across concurrent processes. This can be used to cap the number of actions that may be performed in a certain period of time. More generally, this can be used to enforce a cap on an integer amount that can be incremented or decremented. A limit consists of an action name, a maximum amount, and a period of time in seconds.\n\nInstead of guaranteeing that the number of actions will never exceed the cap the given timeframe, the approach we take is to use a continuously regenerating limit. The amount remaining will constantly increase at a rate of *max / period* until it hits the cap. If, for example, the limit is 60 per minute, a user could increment by 60 at once, then increment by 1 per second forever without hitting the cap. As a consequence, *this algorithm guarantees that the total amount incremented will be less than twice the limit in any given timeframe*.\n\n## Usage\n\n```ruby\nrequire 'traffic_jam'\n\nTrafficJam.configure do |config|\n  config.redis = Redis.new(url: REDIS_URL)\nend\n\nlimit = TrafficJam::Limit.new(\n  :requests_per_user,\n  user.id,\n  max: 3,\n  period: 1 # seconds\n)\nlimit.increment      # =\u003e true\nlimit.increment(2)   # =\u003e true\nlimit.increment      # =\u003e false\nlimit.increment!     # =\u003e raises TrafficJam::LimitExceededError\n\nsleep 1\n\nlimit.increment(2)   # =\u003e true\nlimit.exceeded?      # =\u003e false\nlimit.exceeded?(2)   # =\u003e true\n\nlimit.used           # =\u003e 2\nlimit.remaining      # =\u003e 1\n```\n\n## Configuration\n\nTrafficJam configuration object can be accessed with `TrafficJam.config` or in a block like `TrafficJam.configure { |config| ... }`. Configuration options are:\n\n**redis** (required): A Redis instance to store amounts used for each limit.\n\n**key_prefix** (default: \"traffic_jam\"): The string prefixing all keys in Redis.\n\n### Registering limits\n\nFixed limits can be registered for a key if the cap does not change depending on the value. All instance methods are available on the class.\n\n```ruby\nTrafficJam.configure do |config|\n  config.register(:requests_per_user, 3, 1)\nend\n\nlimit = TrafficJam.limit(:requests_per_user, \"user1\")\nlimit.increment(2)  # =\u003e true\n\nTrafficJam.increment(:requests_per_user, \"user1\", 1)  # =\u003e true\nTrafficJam.used(:requests_per_user, \"user1\")          # =\u003e 3\n```\n\n## Changing cap for a limit\n\nGiven an instance of `TrafficJam::Limit` with a maximum cap and a period, the behavior is to increase the amount remaining at a rate of *max / period* since the last time `increment` was called for the given value. If the cap is defined on a per-value basis, it is good practice to call `increment(0)` if the limit changes.\n\nFor example:\n\n```ruby\nuser.requests_per_hour = 10\n\nlimit = TrafficJam::Limit.new(\n  :requests_per_user, user.id,\n  max: user.requests_per_hour, period: 60 * 60\n)\nlimit.increment(8)  # =\u003e true\n\nsleep 60\n\nlimit.increment(0)\n\nuser.requests_per_hour = 20\nlimit = TrafficJam::Limit.new(\n  :requests_per_user, user.id,\n  max: user.requests_per_hour, period: 60 * 60\n)\nlimit.increment(8)  # =\u003e true\n```\n\n## Running tests\n\nThe `REDIS_URI` environment variable can be set in tests, and defaults to `redis://localhost:6379`.\n\n```\nrake test\n```\n\nTo run a performance/stress test, see the `test/stress.rb` script.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoinbase%2Ftraffic_jam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoinbase%2Ftraffic_jam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoinbase%2Ftraffic_jam/lists"}