Dart implementation for Sliding Window Limiter
A lightweight, storage‑agnostic sliding‑window rate limiter for Dart.
Provide your own storage (e.g., Redis, in‑memory, database) via a tiny
Storage interface, and call consume(tokens) to check and record usage.
Install
- With Dart:
dart pub add sliding_window_limiter - With Flutter:
flutter pub add sliding_window_limiter
Quick start
import 'dart:convert';
import 'package:sliding_window_limiter/sliding_window_limiter.dart';
Future<void> main() async {
final limiter = SlidingWindowLimiter(
id: 'client-IP-or-user-id',
limit: 120, // max tokens per interval
interval: Duration(minutes: 1), // sliding window interval
storage: RedisStorage(), // your Storage implementation
);
// Request 1 token for this operation
final result = await limiter.consume(1);
if (!result.accepted) {
// Inform caller to retry later
print('Retry after: ${result.retryAfter}');
print('Wait time: ${result.waitTime.inSeconds} seconds');
return;
}
print('Remaining tokens: ${result.remainingTokens}');
}
// Example storage (replace with real Redis client)
class RedisStorage implements Storage {
@override
Future<void> save(SlidingWindow window) async {
// Persist window.toJson()
}
@override
Future<SlidingWindow?> fetch(String id) async {
final data = null; // Load JSON string by id
if (data == null) return null;
return SlidingWindow.fromJson(jsonDecode(data));
}
}
If you just need an in‑memory example for tests, this minimal storage works:
class MemoryStorage implements Storage {
final Map<String, SlidingWindow> _store = {};
@override
Future<void> save(SlidingWindow window) async {
_store[window.id] = window;
}
@override
Future<SlidingWindow?> fetch(String id) async {
return _store[id];
}
}
API
-
SlidingWindowLimiter:id: logical key (e.g., user ID, IP).limit: max tokens allowed perinterval.interval: sliding window duration.storage: implementation ofStorage.Future<RateLimit> consume(int tokens): attempts to consumetokens.
-
RateLimitresult:accepted: whether tokens were accepted.remainingTokens: remaining capacity in current window (double).retryAfter: timestamp when enough capacity is available.waitTime: convenienceDurationuntilretryAfter(zero if available now).limit: configured max tokens per interval.
-
Storageinterface:Future<void> save(SlidingWindow window)Future<SlidingWindow?> fetch(String id)
Notes:
tokensmust be > 0 and <=limit.- Use your storage’s TTL equal to
intervalto auto‑expire windows. - The algorithm decays usage continuously within the window for smooth limiting.
License
Apache-2.0 — see LICENSE.
Libraries
- sliding_window_limiter
- Sliding window rate limiter public library.