| Crates.io | lazy-limit |
| lib.rs | lazy-limit |
| version | 1.0.1 |
| created_at | 2025-09-03 14:13:35.509997+00 |
| updated_at | 2025-09-03 14:13:35.509997+00 |
| description | lazy-limit is a lightweight Rust library for rate limiting by IP or custom ID, with support for global, router-specific, and fallback rules. |
| homepage | |
| repository | https://github.com/canmi21/lazy-limit |
| max_upload_size | |
| id | 1822586 |
| size | 45,952 |
Lazy-Limit is a lightweight and flexible Rust library for implementing rate limiting based on IP addresses or custom identifiers. It supports global rate limits, route-specific rules, and an override mode for fine-grained control. Designed for ease of use, it integrates seamlessly with asynchronous Rust applications using Tokio, making it ideal for web servers, APIs, or any networked application requiring rate limiting.
Arc and RwLock for safe concurrent access.Add the following to your Cargo.toml:
[dependencies]
lazy-limit = "1"
Ensure you have the required dependencies:
tokio = { version = "1", features = ["full"] }
once_cell = "1"
The rate limiter must be initialized once at application startup using the init_rate_limiter! macro. You can specify a default global rule, optional route-specific rules, and memory limits.
use lazy_limit::*;
use std::time::Duration as StdDuration;
#[tokio::main]
async fn main() {
init_rate_limiter!(
default: RuleConfig::new(Duration::seconds(1), 5), // 5 req/s globally
max_memory: Some(64 * 1024 * 1024), // 64MB max memory
routes: [
("/api/login", RuleConfig::new(Duration::minutes(1), 3)), // 3 req/min
("/api/public", RuleConfig::new(Duration::seconds(1), 10)), // 10 req/s
("/api/premium", RuleConfig::new(Duration::seconds(1), 20)), // 20 req/s
]
).await;
// Your application logic here
}
Use the limit! macro to check if a request should be allowed based on the identifier (e.g., IP address) and route.
let allowed = limit!("1.1.1.1", "/api/public").await;
if allowed {
println!("Request allowed!");
} else {
println!("Request denied: rate limit exceeded.");
}
Use the limit_override! macro to apply only route-specific rules, ignoring the global limit.
let allowed = limit_override!("1.1.1.1", "/api/premium").await;
if allowed {
println!("Request allowed in override mode!");
} else {
println!("Request denied in override mode.");
}
The library includes a demo in examples/demo.rs that showcases its features:
To run the demo:
cargo run --example demo
Expected output includes detailed test results for each scenario, confirming the rate limiter's behavior.
lazy-limit/
├── examples/
│ └── demo.rs # Example demonstrating rate limiting features
├── src/
│ ├── config.rs # Configuration for rate limiter rules
│ ├── gc.rs # Garbage collection for memory management
│ ├── lib.rs # Main library entry point and macros
│ ├── limiter.rs # Core rate limiter implementation
│ └── types.rs # Data types for duration, rules, and request records
├── Cargo.toml # Project metadata and dependencies
├── LICENSE # MIT License
└── README.md # This file
RuleConfig::new(Duration, limit).routes field in init_rate_limiter!.Example configuration:
let config = LimiterConfig::new(RuleConfig::new(Duration::seconds(1), 5))
.add_route_rule("/api/login", RuleConfig::new(Duration::minutes(1), 3))
.with_max_memory(32 * 1024 * 1024) // 32MB
.with_gc_interval(5); // GC every 5 seconds
The library includes comprehensive unit tests to ensure reliability:
cargo test --all
This runs tests in src/lib.rs and src/limiter.rs, covering:
The rate limiter includes a garbage collector (gc.rs) that:
The garbage collector runs asynchronously in a Tokio task, ensuring non-blocking operation.
init_rate_limiter! multiple times will panic.Contributions are welcome! Please submit issues or pull requests to the GitHub repository.
git checkout -b feature/your-feature).git commit -m "Add your feature").git push origin feature/your-feature).This project is licensed under the MIT License. See the LICENSE file for details.
For questions or support, please open an issue on the GitHub repository.