{"id":19163889,"url":"https://github.com/pggalaviz/limitex","last_synced_at":"2025-10-14T06:36:07.714Z","repository":{"id":57516836,"uuid":"166745757","full_name":"pggalaviz/limitex","owner":"pggalaviz","description":"A pure Elixir distributed rate limiter","archived":false,"fork":false,"pushed_at":"2019-11-25T00:07:48.000Z","size":17,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-25T21:42:16.441Z","etag":null,"topics":["elixir","elixir-lang","limiter","rate-limit","rate-limiter","rate-limiting","ratelimit","ratelimiter"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/limitex","language":"Elixir","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/pggalaviz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-21T03:58:46.000Z","updated_at":"2024-01-19T15:50:59.000Z","dependencies_parsed_at":"2022-09-15T21:23:32.616Z","dependency_job_id":null,"html_url":"https://github.com/pggalaviz/limitex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pggalaviz/limitex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pggalaviz%2Flimitex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pggalaviz%2Flimitex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pggalaviz%2Flimitex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pggalaviz%2Flimitex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pggalaviz","download_url":"https://codeload.github.com/pggalaviz/limitex/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pggalaviz%2Flimitex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279018115,"owners_count":26086281,"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","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["elixir","elixir-lang","limiter","rate-limit","rate-limiter","rate-limiting","ratelimit","ratelimiter"],"created_at":"2024-11-09T09:17:03.652Z","updated_at":"2025-10-14T06:36:07.687Z","avatar_url":"https://github.com/pggalaviz.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Limitex\n\n[![Build Status](https://travis-ci.org/pggalaviz/limitex.svg?branch=master)](https://travis-ci.org/pggalaviz/limitex)\n\nA pure Elixir distributed rate limiter based on the\n[Token Bucket](https://en.wikipedia.org/wiki/Token_bucket) algorithm.\n\n## Description\n\n**Limitex** uses sharded ETS tables with write and read concurrency enabled, node\nclustering is not handled by this package, something like [libcluster](https://github.com/bitwalker/libcluster) is recomended.\n\n#### Example\n\n```elixir\n=\u003e Limitex.check_rate(\"127.0.0.1\", 60_000, 2)\n{:ok, 1}\n=\u003e Limitex.check_rate(\"127.0.0.1\", 60_000, 2)\n{:ok, 2}\n=\u003e Limitex.check_rate(\"127.0.0.1\", 60_000, 2)\n{:error, :rate_limited}\n```\n\n\n## Installation\n\nYou can find **Limitex** in [Hex.pm](https://hex.pm/packages/limitex) and you can add it to your project dependencies:\n\n```elixir\n# mix.exs\ndef deps do\n  [\n    {:limitex, \"~\u003e 0.1.1\"}\n  ]\nend\n```\n## Configuration\n\n**Limitex** will perform scheduled cleanups to remove expired buckets, to handle\nthis, we should provide a cleanup interval and an expiry:\n\n```elixir\n# config.exs\n\nconfig :limitex,\n  cleanup_interval: 60_000, # 1 minute (defaults to 5 minutes)\n  expiry: 300_000 # 5 minutes (defaults to 15 minutes)\n```\n\nTable cleanups will be scheduled every minute in this example (defaults to 5\nminutes), and will delete buckets where expiry has already passed, it's\nimportant to give a value greater than the biggest bucket we create (the\nbucket_time param in `check_rate` function, see below).\n\nSo if we're creating a bucket of 1 hour: `Limitex.check_rate(\"some_id\",\n3_600_000, 20)` we should give a bigger number in our config to prevent cleanup\nto delete buckets which are not yet expired:\n\n```elixir\n# config.exs\n\nconfig :limitex,\n  expiry: 3_800_000\n```\n\n`expiry` defaults to 15 minutes.\n\n## Usage\n\n**Limitex** exports a single function: `check_rate/3` and `check_rate/4`.\n\n* `check_rate(id, bucket_time, limit)`\n* `check_rate(id, bucket_time, limit, increment)`\n\nwhich return an `{:ok, count}` or `{:error, :rate_limited}` tuples.\n\n#### Parameters\n\n* `id` is a string to identify who's requesting the action, it can be\ncomposed of a unique part such as an IP address or a user ID, plus some action\nidentifier (see example below).\n\n* `bucket_time` is the amount of time you want to rate limit the action for the ID, must\n  be given in milliseconds.\n\n* `limit` is an integer which determines how many times we're allowed to perform\n  the action in the given time.\n\n* `increment` each time you call the function, the count to reach the limit is\n  increased by 1 as a default, you can alternatively pass an arbitrary integer\n  to increase the limit.\n\n## Examples\n\nInside your app you can call it inside any function:\n\n```elixir\ndefmodule MyApp.Upload do\n\n  def upload(video_data, user_id) do\n    case Limitex.check_rate(\"upload:#{user_id}\", 60_000, 5) do\n      {:ok, _count} -\u003e\n        # upload the video, somehow\n      {:error, :rate_limited} -\u003e\n        # deny the request\n    end\n  end\n\nend\n```\n\nSo in the above example we'll limit user's uploads to 5 every 60 seconds.\n\n## Benchmarks\n\nBasic benchmarks can be run with `mix bench`.\n\nThese benchmarks were run on an iMac 4 GHz Intel Core i7 w/ 32GB RAM.\n\n```shell\nName                             ips        average  deviation         median         99th %\ncheck_rate (100,000)        388.48 K        2.57 μs   ±892.63%        1.98 μs        4.98 μs\ncheck_rate (1,000,000)      395.01 K        2.53 μs   ±898.74%           2 μs           4 μs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpggalaviz%2Flimitex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpggalaviz%2Flimitex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpggalaviz%2Flimitex/lists"}