{"id":21166608,"url":"https://github.com/meemaw/rate-limiting","last_synced_at":"2026-04-27T17:05:06.049Z","repository":{"id":96155574,"uuid":"160405923","full_name":"Meemaw/rate-limiting","owner":"Meemaw","description":"State of the art rate-limiting in Java.","archived":false,"fork":false,"pushed_at":"2018-12-04T20:03:13.000Z","size":101,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-01T17:59:31.874Z","etag":null,"topics":["cache","distributed-systems","fixed-window","hazelcast","java","jcache","microservices","rate-limiting","redis","sliding-window","token-bucket"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Meemaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2018-12-04T19:07:02.000Z","updated_at":"2025-05-14T05:57:28.000Z","dependencies_parsed_at":"2023-04-09T05:00:54.088Z","dependency_job_id":null,"html_url":"https://github.com/Meemaw/rate-limiting","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Meemaw/rate-limiting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meemaw%2Frate-limiting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meemaw%2Frate-limiting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meemaw%2Frate-limiting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meemaw%2Frate-limiting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Meemaw","download_url":"https://codeload.github.com/Meemaw/rate-limiting/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meemaw%2Frate-limiting/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32345883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"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":["cache","distributed-systems","fixed-window","hazelcast","java","jcache","microservices","rate-limiting","redis","sliding-window","token-bucket"],"created_at":"2024-11-20T14:51:40.648Z","updated_at":"2026-04-27T17:05:06.013Z","avatar_url":"https://github.com/Meemaw.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rate Limiting\n\n### [About][about]\n\nState of the art rate-limiting in Java. Implemented algorithms:\n  - [Token bucket algorithm][token-bucket]\n  - Fixed window algorithm\n  - Sliding window log algorithm\n\nHighly customizable and extensible implementation with assumptions about the environment used - it can be easily extended to be used with any key-value storage backend such as:\n  - [Hazelcast][hazelcast]\n  - [Redis][redis]\n  - ...\n\nSee [Hazelcast][hazelcast-storage] or [JCache][jcache-storage] example storage implementation\n\n\n### [Features][features]\n\n- Multiple policies per user\n- Blazing speed\n- Multiple algorithms per user\n- Support for distributed environments\n- Pluggable storage backend system\n- Generic storage key types\n\n### [Usage][usage]\n\nTo perform Rate Limiting implement `RateLimiter` interface or use existing `RateLimiterImpl`. You can implement use your key-value database by implementing `StorageBackend` interface or use the existing [HazelcastStorage][hazelcast-storage] implementation. \n\n### [Examples][examples]\n\n##### [Simple example][simple-example-source]\n\n```java\nStorageBackend\u003cString\u003e storageBackend = new InMemoryStorageBackend\u003c\u003e(); // in memory impl.\nEntryStorage entryStorage = new DistributedEntryStorage(storageBackend); // async mode\nRateLimiter rateLimiter = RateLimiting.withStorage(entryStorage);\n\nif (rateLimiter.conformsRateLimits(\"userIdentifier\")) {\n    System.out.println(\"User has no policies so this will be printed!\");\n} else {\n    System.out.println(\"Too many requests!\");\n}\n```\n\n##### Advanced rate limit filter example (javax)\n\n[Full source][rate-limit-filter-source]\n\n```java\npublic abstract class RateLimitFilter implements ContainerRequestFilter {\n\n    @Override\n    public void filter(ContainerRequestContext req) throws IOException {\n        try {\n            Optional\u003cString\u003e identifier = getIdentifier(req);\n            if (!identifier.isPresent()) {\n                return;\n            }\n\n            ConsumptionEntry consumptionEntry = getRateLimiter().conformRateLimitsWithConsumption(identifier.get());\n            long retryAfter = TimeUnit.NANOSECONDS.toMillis(consumptionEntry.getNanosUntilConsumption());\n\n            // Inject headers\n            response.addHeader(RATE_LIMIT_REMAINING_HEADER,\n                    String.valueOf(consumptionEntry.getRemainingTokens()));\n            response.addHeader(RETRY_AFTER_HEADER, String.valueOf(retryAfter));\n\n            if (!consumptionEntry.doesConform()) {\n                req.abortWith(createRateLimitResponse(consumptionEntry));\n            }\n        } catch (RateLimiterException ex) {\n        }\n    }\n\n}\n```\n\n\nIf you need custom serialization combined with your custom storage-backend extend base classes e.g. `SimpleRefillPolicy`, `AbstractRecord` and `AbstractEntry` and implement required serialization methods.\n\n##### [Configuration][configuration]\n\n###### Env variables\n- `ratelimit.map.users.limits`: Hazelcast IMap name (default `ratelimit.map.users.limits)`\n- `distributedStorageBackendTimeout`: Timeout for rate limiter pass-through mode in ms (default `500ms`). You should decrease this in production to avoid long latencies in case of StorageBackend failures.\n\n##### [Scheduling][scheduling]\n\nIt turns out rate limiting algorithms are very appropriate for scheduling.\n\n[Scheduling example][scheduling-example-source]\n\n```java\nEntryBuilder builder = RateLimiting.schedulerBuilder().withAlgorithm(RateLimitAlgorithm.TOKEN_BUCKET);\nRefillPolicy policy = SimpleRefillPolicy.perSecond(2);\nRateLimitEntry record = builder.withRefillPolicy(policy).build();\n\nlong start = System.currentTimeMillis();\nwhile (record.tryConsume(1)) {\n\tdouble secondsPassed = (System.currentTimeMillis() - start) / 1000.0;\n\tSystem.out.println(secondsPassed); // or someVeryExpensiveTask();\n}\n```\n\n###### Output:\n\n```sh\n0.502\n1.004\n1.504\n2.006\n2.508\n3.011\n...\n```\n\n\n[hazelcast-storage]: https://github.com/Meemaw/rate-limiting/blob/master/ratelimit-hazelcast/src/main/java/io/github/meemaw/ratelimit/hazelcast/HazelcastStorage.java\n[jcache-storage]: https://github.com/Meemaw/rate-limiting/blob/master/ratelimit-jcache/src/main/java/io/github/meemaw/ratelimit/jcache/JCacheStorage.java\n[about]: https://github.com/Meemaw/rate-limiting#about\n[features]: https://github.com/Meemaw/rate-limiting#features\n[usage]: https://github.com/Meemaw/rate-limiting#usage\n[configuration]: https://github.com/Meemaw/rate-limiting#configuration\n[scheduling]: https://github.com/Meemaw/rate-limiting#scheduling\n[hazelcast]: https://hazelcast.com/\n[redis]: https://redis.io/\n[token-bucket]: https://en.wikipedia.org/wiki/Token_bucket\n[simple-example]: https://github.com/Meemaw/rate-limiting#simple-example\n[simple-example-source]: https://github.com/Meemaw/rate-limiting/blob/master/ratelimit-examples/src/main/java/io/github/meemaw/ratelimit/examples/SimpleRateLimitingExample.java\n[scheduling-example-source]: https://github.com/Meemaw/rate-limiting/blob/master/ratelimit-examples/src/main/java/io/github/meemaw/ratelimit/examples/SchedulingExample.java\n[examples]: https://github.com/Meemaw/rate-limiting/tree/master/ratelimit-examples/src/main/java/io/github/meemaw/ratelimit/examples\n[rate-limit-filter-source]: https://github.com/Meemaw/rate-limiting/blob/master/ratelimit-examples/src/main/java/io/github/meemaw/ratelimit/examples/RateLimitFilter.java","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeemaw%2Frate-limiting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeemaw%2Frate-limiting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeemaw%2Frate-limiting/lists"}