cloudiful-rate-limiter
cloudiful-rate-limiter is an async throttling library for keyed resource access.
It answers one question: can this key access a resource now, and if not, how long should the caller wait?
The published package name is cloudiful-rate-limiter, while the Rust library import is rate_limiter.
Links:
- Gitea: https://gitea.cloud1ful.com/crates/rate-limiter
- docs.rs: https://docs.rs/cloudiful-rate-limiter
- crates.io: https://crates.io/crates/cloudiful-rate-limiter
Version 0.1.0 exposes:
RateLimitPolicy::MinIntervalfor fixed minimum gaps between accessesRateLimitPolicy::PerMinutefor evenly spaced requests per minuteLocalRateLimiterfor in-process throttling- optional
ValkeyRateLimiterfor shared throttling across instances acquire,try_acquire, andpeekAPIs
Non-goals for this crate:
- job scheduling
- retries or backoff policies
- token buckets
- concurrency semaphores
- HTTP middleware
- business-specific key derivation
Add the crate
[]
= { = "cloudiful-rate-limiter", = "0.1.0" }
= { = "1", = ["macros", "rt-multi-thread", "time"] }
Enable shared Valkey backend:
[]
= { = "cloudiful-rate-limiter", = "0.1.0", = ["valkey"] }
= { = "1", = ["macros", "rt-multi-thread", "time"] }
Core concepts
policy: throttling rulekey: explicit caller-provided scope such aseastmoney:quotebackend: state store implementationacquire: consume one access slot, sleeping internally if neededtry_acquire: consume one slot only if currently allowedpeek: inspect without consuming a slot
This crate does not decide when a job starts. A scheduler, worker, CLI, or HTTP client controls that part.
Example: local minimum interval
use Duration;
use ;
async
Example: per-minute policy
use RateLimitPolicy;
use Duration;
let interval = per_minute.unwrap.interval.unwrap;
assert_eq!;
Example: shared Valkey limiter
use Duration;
use ;
async
Backend semantics
LocalRateLimiter uses process-local monotonic Instant.
ValkeyRateLimiter stores key -> next_allowed_timestamp_ms and uses one Lua script so competing instances observe atomic acquire decisions.
PerMinute currently maps to evenly spaced slots. It is not a token bucket.
Valkey integration tests
The Valkey integration tests are marked ignored so default CI stays hermetic. Run them explicitly with a reachable server:
RATE_LIMITER_VALKEY_URL=redis://127.0.0.1:6379/
In Gitea Actions, set the RATE_LIMITER_VALKEY_URL secret to enable the external Valkey integration test step in .gitea/workflows/ci.yml.