{"id":40021997,"url":"https://github.com/nzin/traefik-cluster-ratelimit","last_synced_at":"2026-01-19T03:32:04.382Z","repository":{"id":255495381,"uuid":"851456649","full_name":"nzin/traefik-cluster-ratelimit","owner":"nzin","description":"Traefik Cluster Rate Limiter (using a shared Redis server)","archived":false,"fork":false,"pushed_at":"2025-12-22T13:34:42.000Z","size":188,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-24T00:30:43.401Z","etag":null,"topics":["traefik","traefik-plugin"],"latest_commit_sha":null,"homepage":"","language":"Go","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/nzin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-03T06:13:47.000Z","updated_at":"2025-12-22T13:34:24.000Z","dependencies_parsed_at":"2024-09-05T19:59:00.386Z","dependency_job_id":"89d329f0-57d2-4a9e-985a-8f4280dbb6c9","html_url":"https://github.com/nzin/traefik-cluster-ratelimit","commit_stats":null,"previous_names":["nzin/traefik-cluster-ratelimit"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/nzin/traefik-cluster-ratelimit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzin%2Ftraefik-cluster-ratelimit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzin%2Ftraefik-cluster-ratelimit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzin%2Ftraefik-cluster-ratelimit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzin%2Ftraefik-cluster-ratelimit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nzin","download_url":"https://codeload.github.com/nzin/traefik-cluster-ratelimit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzin%2Ftraefik-cluster-ratelimit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28560319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T03:31:16.861Z","status":"ssl_error","status_checked_at":"2026-01-19T03:31:15.069Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["traefik","traefik-plugin"],"created_at":"2026-01-19T03:32:04.326Z","updated_at":"2026-01-19T03:32:04.377Z","avatar_url":"https://github.com/nzin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# traefik-cluster-ratelimit\n\nTraefik comes with a default [rate limiter](https://doc.traefik.io/traefik/middlewares/http/ratelimit/) middleware, but the rate limiter doesn't share a state if you are using several instance of Traefik (think kubernetes HA deployment for example).\n\nThis plugin is here to solve this issue: using a Redis as a common state, this plugin implement the [token bucket algorithm](https://en.wikipedia.org/wiki/Token_bucket).\n\n## Configuration\n\nYou need to setup the static and dynamic configuration\n\nThe following declaration (given here in YAML) defines the plugin:\n\n```yml\n# Static configuration\n\nexperimental:\n  plugins:\n    clusterRatelimit:\n      moduleName: \"github.com/nzin/traefik-cluster-ratelimit\"\n      version: \"v1.1.1\"\n```\n\nHere is an example of a file provider dynamic configuration (given here in YAML), where the interesting part is the http.middlewares section:\n\n```yml\n# Dynamic configuration\n\nhttp:\n  routers:\n    my-router:\n      rule: host(`demo.localhost`)\n      service: service-foo\n      entryPoints:\n        - web\n      middlewares:\n        - my-middleware\n\n  services:\n   service-foo:\n      loadBalancer:\n        servers:\n          - url: http://127.0.0.1:5000\n  \n  middlewares:\n    my-middleware:\n      plugin:\n        clusterRatelimit:\n          average: 50\n          burst: 100\n```\n\nWith a kubernetesingress provider:\n\n```yml\napiVersion: traefik.io/v1alpha1\nkind: Middleware\nmetadata:\n  name: clusterratelimit\n  namespace: ingress-traefik\nspec:\n  clusterRatelimit:\n    average: 100\n    burst: 200\n---\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: example-ingress\n  namespace: ingress-traefik\n  annotations:\n    traefik.ingress.kubernetes.io/router.middlewares: ingress-traefik-clusterratelimit@kubernetescrd\nspec:\n  rules:\n  - host: example.com\n    http:\n      paths:\n      - path: /\n        pathType: Prefix\n        backend:\n          service:\n            name: example-service\n            port:\n              number: 80\n```\n\n## Extra configuration\n\nThe `average` and the `burst` are the number of allowed connection per second, there are other variables:\n\n| Variable                    | Description                                        | default    |\n|-----------------------------|----------------------------------------------------|------------|\n| period                      | the period (in seconds) of the rate limiter window | 1          |\n| average                     | allowed requests per \"period\" ( 0 = unlimited)     |            |\n| burst                       | allowed burst requests per \"period\"                |            |\n| redisAddress                | address of the redis server                        | redis:6379 |\n| redisDb                     | redis db to use                                    | 0          |\n| redisPassword               | redis authentication (if any)                      |            |\n| sourceCriterion.*           | defines what criterion is used to group requests. See next | ipStrategy |\n| sourceCriterion.ipStrategy  | client IP based source                             |            |\n| sourceCriterion.ipStrategy.depth | tells Traefik to use the X-Forwarded-For header and select the IP located at the depth position |    |\n| sourceCriterion.ipStrategy.excludedIPs | list of X-Forwarded-For IPs that are to be excluded | |\n| sourceCriterion.requestHost | based source on request host                       |            |\n| sourceCriterion.requestHeaderName | Name of the header used to group incoming requests|       |\n| breakerThreshold            | number of failed connection before pausing Redis   | 3          |\n| breakerReattempt            | nb seconds before attempting to reconnect to Redis | 15         |\n| redisConnectionTimeout      | redis connection timeout (in seconds)              | 2          |\n| whitelistIPs                | list of IP addresses or CIDR ranges that bypass rate limiting |            |\n\nNotes:\n- for more information about sourceCriteron check the Traefik [ratelimit](https://doc.traefik.io/traefik/middlewares/http/ratelimit/) page\n- regarding redispassword, if you dont want to set it in clear text in the traefik configuration, you can specify a variable name starting with '$'. For example `$REDIS_PASSWORD` will use the `REDIS_PASSWORD` environment variable\n- whitelistIPs allows you to specify IP addresses or CIDR ranges that will completely bypass rate limiting. This is useful when you have groups of users sharing the same IP address. The IP extraction for whitelist checking uses the same IP strategy as defined in sourceCriterion.ipStrategy, or falls back to RemoteAddr if not specified.\n\nA full example would be\n\n```yml\n# Dynamic configuration\n\nhttp:\n  ...\n  middlewares:\n    my-middleware:\n      plugin:\n        clusterRatelimit:\n          average: 5\n          burst: 10\n          period: 10\n          sourceCriterion:\n            ipStrategy:\n              depth: 2\n              excludedIPs:\n              - 127.0.0.1/32\n              - 192.168.1.7          \n          redisAddress: redis:6379\n          redisPassword: $REDIS_AUTH_PASSWORD\n          redisConnectionTimeout: 2\n          whitelistIPs:\n            - \"192.168.1.1\"\n            - \"10.0.0.0/8\"\n            - \"172.16.0.0/12\"\n```\n\n## Circuit-breaker\n\nIf the Redis server is not available, we will stop talking to it, and let pass through.\nAs mentionned above there are 2 variables you can use to change the default behaviour: `breakerThreshold` and `breakerReattempt`. Usually you dont need to tweak that.\n\n## Benchmark\n\nYou can test traefik with the rate limiter with some tools. For example with vegeta (you probably need to install it):\n```sh\ndocker-compose up -d\n\necho \"GET http://localhost:8000/\" | vegeta attack -duration=5s -rate=200 | tee results.bin | vegeta report\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnzin%2Ftraefik-cluster-ratelimit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnzin%2Ftraefik-cluster-ratelimit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnzin%2Ftraefik-cluster-ratelimit/lists"}