rate-guard-core
A comprehensive rate limiting library for Rust applications with multiple thread-safe algorithms.
Features
4 Rate Limiting Algorithms: Token Bucket, Fixed Window Counter, Sliding Window Counter, and Approximate Sliding Window
Thread-Safe: All algorithms use non-blocking locks
Zero Dependencies: Lightweight with no external dependencies
Flexible Time: Works with any time unit via abstract "ticks"
Configurable Tick Precision: Compile-time feature flags allow choosing u64 (default) or u128 for tick units
Rust 1.60+: Compatible with older Rust versions
Quick Start
from crate.io
Add to your Cargo.toml:
[]
= { = "0.7.1" }
from Github
Add to your Cargo.toml:
[]
= { = "https://github.com/Kuanlin/rate-guard-core", = "v0.7.1" }
Tick Precision (u64 / u128)
By default, the crate uses u64 as the tick unit, allowing up to ~584 years of nanosecond-resolution time.
If your application needs ultra-long durations or ultra-high precision, you can enable u128 support via feature flags:
from crate.io
[]
= { = "0.7.1", = false, = ["tick-u128"] }
from Github
[]
= { = "https://github.com/Kuanlin/rate-guard-core", = "v0.7.1", = false, = ["tick-u128"] }
Usage Examples
Token Bucket
Perfect for APIs that allow occasional bursts while maintaining average rate:
use ;
let config = TokenBucketCoreConfig ;
// Option 1: Using `into()` – idiomatic Rust way to convert config into limiter
let limiter: TokenBucketCore = config.into;
// Option 2: Using `from()` – explicitly convert config into limiter
let limiter_alt = from;
Fixed Window Counter
use ;
let config = FixedWindowCounterCoreConfig ;
// Option 1: Using `into()` – idiomatic Rust way to convert config into limiter
let limiter: FixedWindowCounterCore = config.into;
// Option 2: Using `from()` – explicitly convert config into limiter
let limiter_alt = from;
Sliding Window Counter
use ;
let config = SlidingWindowCounterCoreConfig ;
// Option 1: Using `into()` – idiomatic Rust way to convert config into limiter
let limiter: SlidingWindowCounterCore = config.into;
// Option 2: Using `from()` – explicitly convert config into limiter
let limiter_alt = from;
Approximate Sliding Window
A memory-optimized version of sliding window counter.
Formula:
Used = (1 - X%) * lastWindow + currentWindow where X is the proportion of request time within the current window.
use ;
let config = ApproximateSlidingWindowCoreConfig ;
// Option 1: Using `into()` – idiomatic Rust way to convert config into limiter
let limiter: ApproximateSlidingWindowCore = config.into;
// Option 2: Using `from()` – explicitly convert config into limiter
let limiter_alt = from;
Both into() and from() are functionally equivalent in Rust.
into() is shorter and idiomatic; from() is more explicit and beginner-friendly.
These examples are duplicated to help both Rust newcomers and non-Rust readers understand the conversion logic.
Approximate Sliding Window
A memory-optimized version of sliding window counter.
Formula:
Used = (1 - X%) * lastWindow + currentWindow where X is the proportion of request time within the current window.
use ;
let config = ApproximateSlidingWindowCoreConfig ;
let limiter: ApproximateSlidingWindowCore = from;
Error Handling
All limiters' try_acquire_at returns SimpleRateLimitResult:
use ;
match limiter.try_acquire_at
Verbose Error Reporting
Each limiter also supports try_acquire_verbose_at(tick, tokens), which returns a VerboseRateLimitError with richer diagnostics:
ContentionFailure: Lock was unavailable
ExpiredTick { min_acceptable_tick }: Time went backwards
BeyondCapacity { acquiring, capacity }: Requested tokens exceed max
InsufficientCapacity { acquiring, available, retry_after_ticks }: Not enough tokens now, but suggests how long to wait before retrying
use ;
match limiter.try_acquire_verbose_at
try_acquire_verbose_at is useful for retry logic, logging, or adaptive throttling.
Time Management
The library uses abstract "ticks" for time. You can map any time source:
// Seconds
let tick = now.duration_since.unwrap.as_secs;
// Milliseconds
let tick = now.duration_since.unwrap.as_millis as u64;
// Custom time
let tick = my_monotonic_timer.elapsed_ticks;
Thread Safety
use Arc;
use thread;
use TokenBucketCore;
let limiter = new;
for _ in 0..10
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.