RateLimiter - sebamar88/bytekit GitHub Wiki
EN: URL-based rate limiting with two implementations: Token Bucket (burst-friendly) and Sliding Window (precise). Prevents overwhelming APIs by tracking requests per URL hostname.
ES: Limitación de tasa basada en URL con dos implementaciones: Token Bucket (permite ráfagas) y Sliding Window (preciso). Previene sobrecargar APIs rastreando solicitudes por hostname de URL.
import { RateLimiter, SlidingWindowRateLimiter } from "bytekit/rate-limiter";
// or | o también:
import { RateLimiter, SlidingWindowRateLimiter } from "bytekit";const limiter = new RateLimiter(config?: RateLimiterConfig);
const limiter = new SlidingWindowRateLimiter(config?: RateLimiterConfig);| Property / Propiedad | Type / Tipo | Default | Description (EN) | Descripción (ES) |
|---|---|---|---|---|
maxRequests |
number |
100 |
Max requests allowed in the window | Máximo de solicitudes permitidas en la ventana |
windowMs |
number |
60000 |
Time window in milliseconds (1 min) | Ventana de tiempo en milisegundos (1 min) |
keyGenerator |
(url: string) => string |
url => new URL(url).hostname |
Function to derive the rate-limit key from a URL | Función para derivar la clave de rate-limit de una URL |
EN: Both
RateLimiterandSlidingWindowRateLimitershare the same methods.ES: Tanto
RateLimitercomoSlidingWindowRateLimitercomparten los mismos métodos.
| Method / Método | Signature / Firma | Description (EN) | Descripción (ES) |
|---|---|---|---|
isAllowed |
isAllowed(url: string): boolean |
Checks if a request to this URL is allowed | Verifica si una solicitud a esta URL está permitida |
getStats |
getStats(url: string): RateLimiterStats |
Returns stats for a URL | Devuelve estadísticas para una URL |
reset |
reset(url: string): void |
Resets the limit for a specific URL | Reinicia el límite para una URL específica |
resetAll |
resetAll(): void |
Resets all rate limits | Reinicia todos los límites |
waitForAllowance |
waitForAllowance(url: string): Promise<void> |
Waits (blocks) until a request is allowed | Espera (bloquea) hasta que una solicitud sea permitida |
interface RateLimiterStats {
remaining: number; // Requests remaining in the window / Solicitudes restantes en la ventana
limit: number; // Max requests per window / Máximo de solicitudes por ventana
resetAt: number; // Timestamp when the window resets / Timestamp de reinicio de ventana
retryAfter?: number; // Seconds to wait if limit exceeded / Segundos de espera si se excedió el límite
}EN: Starts with a full "bucket" of tokens. Each request consumes one token. Tokens refill gradually over time. This allows bursts — you can use all tokens at once, then wait for refills.
ES: Comienza con un "cubo" lleno de tokens. Cada solicitud consume un token. Los tokens se rellenan gradualmente con el tiempo. Esto permite ráfagas — puedes usar todos los tokens de una vez, luego esperar recargas.
[████████████] 100 tokens → burst 20 requests → [████████░░░░] 80 remaining
↓ time passes
[██████████░░] 90 remaining (refilled)
EN: Tracks exact timestamps of each request. Counts only requests within the last
windowMsmilliseconds. More precise but uses more memory because it stores every timestamp.ES: Rastrea las marcas de tiempo exactas de cada solicitud. Cuenta solo solicitudes dentro de los últimos
windowMsmilisegundos. Más preciso pero usa más memoria porque almacena cada timestamp.
|--- windowMs (60s) ---|
[req][req][req]........[req] → count = 4 (within window)
↑ old requests expire as time passes / las solicitudes antiguas expiran con el tiempo
| Scenario / Escenario | Recommended / Recomendado |
|---|---|
| General-purpose API limiting |
RateLimiter (Token Bucket) |
| APIs with strict per-second limits | SlidingWindowRateLimiter |
| Allow occasional bursts |
RateLimiter (Token Bucket) |
| Need precise counting | SlidingWindowRateLimiter |
import { RateLimiter } from "bytekit/rate-limiter";
const limiter = new RateLimiter({
maxRequests: 10,
windowMs: 60_000, // 10 requests per minute per hostname
});
const url = "https://api.example.com/users";
if (limiter.isAllowed(url)) {
const res = await fetch(url);
// ...
} else {
const stats = limiter.getStats(url);
console.log(`Rate limited. Retry in ${stats.retryAfter}s`);
}import { SlidingWindowRateLimiter } from "bytekit/rate-limiter";
const limiter = new SlidingWindowRateLimiter({
maxRequests: 5,
windowMs: 10_000, // 5 requests per 10 seconds
});
for (let i = 0; i < 8; i++) {
const allowed = limiter.isAllowed("https://api.example.com/data");
console.log(`Request ${i + 1}: ${allowed ? "✅ Allowed" : "❌ Blocked"}`);
}
// ✅ ✅ ✅ ✅ ✅ ❌ ❌ ❌const limiter = new RateLimiter({ maxRequests: 2, windowMs: 5000 });
async function safeFetch(url: string) {
// EN: Blocks until the rate limiter allows the request
// ES: Bloquea hasta que el rate limiter permita la solicitud
await limiter.waitForAllowance(url);
return fetch(url);
}// EN: Rate limit per full path, not just hostname
// ES: Limitar tasa por ruta completa, no solo hostname
const limiter = new RateLimiter({
maxRequests: 30,
windowMs: 60_000,
keyGenerator: (url) => {
const u = new URL(url);
return `${u.hostname}${u.pathname}`;
},
});const stats = limiter.getStats("https://api.example.com/users");
console.log(`Remaining: ${stats.remaining}/${stats.limit}`);
console.log(`Resets at: ${new Date(stats.resetAt).toISOString()}`);
if (stats.retryAfter) {
console.log(`Retry after: ${stats.retryAfter}s`);
}EN: Both rate limiters are URL-based — they group requests by the key derived from the URL (hostname by default). They do not limit by action type (GET vs POST). If you need per-action limits, use a custom
keyGeneratorthat includes the HTTP method.ES: Ambos rate limiters son basados en URL — agrupan solicitudes por la clave derivada de la URL (hostname por defecto). No limitan por tipo de acción (GET vs POST). Si necesitas límites por acción, usa un
keyGeneratorpersonalizado que incluya el método HTTP.
- RequestDeduplicator — Deduplicate concurrent identical requests / Deduplicar solicitudes idénticas concurrentes
- RequestCache — Cache responses to reduce total requests / Cachear respuestas para reducir solicitudes totales
- ApiClient — HTTP client for building resilient request pipelines / Cliente HTTP para construir pipelines de solicitudes resilientes