Cleanup
Provider builders start stale-state cleanup by default. Cleanup is separate from lazy bucket expiration performed by reads and admission operations.

Configure startup
use std::time::Duration;
use trypema::RateLimiterBuilder;
use trypema::local::LocalRateLimiterProvider;
let provider = LocalRateLimiterProvider::builder()
.stale_after(Duration::from_secs(600))
.cleanup_interval(Duration::from_secs(30))
.disable_cleanup()
.build()
.unwrap();
stale_after is the inactivity period before a key becomes cleanup-eligible;
cleanup_interval is how often the provider scans. Their defaults are 10 minutes and 30 seconds.
disable_cleanup()prevents automatic startup.enable_cleanup()enables automatic startup.cleanup_enabled(bool)supports runtime-conditional configuration.
Control after construction
All providers expose idempotent controls:
provider.start_cleanup_loop();
provider.stop_cleanup_loop();
Hybrid synchronization remains mandatory and independent of optional stale-state cleanup.
What one cleanup pass does
One cleanup pass has these steps:
- It removes the stale keys of the absolute strategy.
- It removes the stale keys of the suppressed strategy.
A failure of one step does not stop the other step. The provider logs the error, and the next pass tries again.
The Redis and hybrid providers remove stale keys from Redis in batches of 500. The first batch
sets the cutoff time of the pass. The pass continues until no key that was stale at that time
stays. Thus, one script call does not block Redis for a long time when many keys become stale
together. The Redis clear() uses the same batches.
A hybrid strategy removes its stale local state after its Redis step succeeds. If the Redis step fails, the local state stays.

