{"id":16513897,"url":"https://github.com/twin/r8limit","last_synced_at":"2025-12-12T11:50:56.727Z","repository":{"id":57658284,"uuid":"403436851","full_name":"TwiN/r8limit","owner":"TwiN","description":"Dead simple rate limiter for Rust","archived":false,"fork":false,"pushed_at":"2022-06-12T20:40:24.000Z","size":13,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T12:06:16.145Z","etag":null,"topics":["library","rate-limit","rate-limiter","rate-limiting"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/r8limit","language":"Rust","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/TwiN.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}},"created_at":"2021-09-05T23:56:20.000Z","updated_at":"2024-09-11T11:59:57.000Z","dependencies_parsed_at":"2022-09-16T04:20:29.277Z","dependency_job_id":null,"html_url":"https://github.com/TwiN/r8limit","commit_stats":null,"previous_names":["twinproduction/r8limit"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TwiN%2Fr8limit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TwiN%2Fr8limit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TwiN%2Fr8limit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TwiN%2Fr8limit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TwiN","download_url":"https://codeload.github.com/TwiN/r8limit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238597386,"owners_count":19498396,"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":["library","rate-limit","rate-limiter","rate-limiting"],"created_at":"2024-10-11T16:10:46.544Z","updated_at":"2025-10-08T04:07:19.264Z","avatar_url":"https://github.com/TwiN.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# r8limit\n[![Crates.io](https://img.shields.io/crates/v/r8limit)](https://crates.io/crates/r8limit)\n![Downloads](https://img.shields.io/crates/d/r8limit)\n[![docs.rs](https://img.shields.io/badge/docs.rs-rustdoc-green)](https://docs.rs/r8limit)\n\nA dead simple Rust library for rate limiting.\n\n## Usage\nIn your `Cargo.toml`:\n```toml\n[dependencies]\nr8limit = \"0.2\"\n```\n\nIn your code:\n```rust\nuse std::time::Duration;\n\nfn main() {\n    // Allow 3 attempts every 5 seconds\n    let mut limiter = r8limit::RateLimiter::new(3, Duration::from_secs(5));\n    println!(\"{}\", limiter.attempt()); // true\n    println!(\"{}\", limiter.attempt()); // true\n    println!(\"{}\", limiter.attempt()); // true\n    println!(\"{}\", limiter.attempt()); // false\n}\n```\n\n## Refill policies\nThe refill policy is what determines how the number of executions in an interval are refilled.\n\n### Full\nBy default, the refill policy is set to `Full`. This means that every time the difference between now and the\nstart of the current window has reached or exceeded the specified interval, the number of executions is reset to\nthe maximum number of executions allowed during the interval.\n\n```rust\nuse std::time::Duration;\nuse std::thread::sleep;\nuse crate::RateLimiter;\n\nfn main() {\n    let mut limiter = RateLimiter::new(3, Duration::from_secs(1));\n    limiter.attempt(); // returns true; executions remaining in window: 2\n    limiter.attempt(); // returns true; executions remaining in window: 1\n    limiter.attempt(); // returns true; executions remaining in window: 0\n    limiter.attempt(); // returns false; executions remaining in window: 0\n    // Remember that the interval is set to 1s\n    sleep(Duration::from_millis(500)); // executions remaining in window: 0\n    // As you can see, even though half of the interval has passed, there are still 0 executions available.\n    assert_eq!(limiter.attempt(), false); // returns false; executions remaining for window: 0\n    // That is what the default refill policy, RefillPolicy::Full, does.\n    // We'll sleep for the remainder of the window, which means that the next attempt will reset the window\n    sleep(Duration::from_millis(500)); // executions remaining in window: 3\n    limiter.attempt(); // returns true; executions remaining in window: 2\n    limiter.attempt(); // returns true; executions remaining in window: 1\n    limiter.attempt(); // returns true; executions remaining in window: 0\n    limiter.attempt(); // returns false; executions remaining in window: 0\n}\n```\n\n### Gradual\nUnlike the `Full` refill policy, the `Gradual` refill policy does not wait until the interval has completely elapsed\nto refill the number of executions remaining. \n\n```rust\nuse std::time::Duration;\nuse std::thread::sleep;\nuse crate::{RateLimiter, RefillPolicy};\n\nfn main() {\n    let mut limiter = RateLimiter::new(2, Duration::from_millis(500)).with_refill_policy(RefillPolicy::Gradual);\n    limiter.attempt(); // returns true; executions remaining in window: 1\n    limiter.attempt(); // returns true; executions remaining in window: 0\n    limiter.attempt(); // returns false; executions remaining in window: 0\n    // The Gradual refill policy calculates the percentage of the interval which has \n    // elapsed, and multiplies that by the number of executions allowed per interval.\n    // This means that if we wait for half of the interval, half of the executions will become available again\n    sleep(Duration::from_millis(250)); // executions remaining in window: 1\n    limiter.attempt(); // returns true; executions remaining in window: 0\n    limiter.attempt(); // returns false; executions remaining in window: 0\n    sleep(Duration::from_millis(500)); // executions remaining in window: 2\n    limiter.attempt(); // returns true; executions remaining in window: 1\n    limiter.attempt(); // returns true; executions remaining in window: 0\n    limiter.attempt(); // returns false; executions remaining in window: 0\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwin%2Fr8limit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwin%2Fr8limit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwin%2Fr8limit/lists"}