AniUI Academy

Rate limit with a sliding window

hardAsync & Promises+350 XPPractice

Public APIs publish limits like 'ten requests per second' and answer with 429 when you exceed them. A client-side limiter keeps you under the line without you having to think about it at every call site.

Implement createRateLimiter(limit, windowMs), returning a schedule(task) function. task takes no arguments and returns a promise; schedule returns a promise that settles with that task's own result. At most limit tasks may be **started** within any windowMs window. A task that cannot start yet waits, and waiting tasks start in the order they were scheduled. Once a start falls further than windowMs in the past it no longer counts against the limit, so a slot frees up. A task that rejects only rejects its own promise and does not hold up the ones behind it.

Arguments

limitnumber
Maximum number of task starts allowed in any windowMs interval.
windowMsnumber
The sliding window size in milliseconds.

Returns

(task: () => Promise<T>) => Promise<T> — A schedule function. Starts the task when a slot is free and resolves with its result.

Examples

const schedule = createRateLimiter(10, 1000); // 10 per second

// Fire 50 requests — only 10 start per second, the rest queue in order.
const results = await Promise.all(
  urls.map((url) => schedule(() => fetch(url)))
);

Keeps you under a published rate limit without thinking about it per call site.

What it has to do

  • Start at most limit tasks within any windowMs window.
  • Start the first limit tasks without any delay.
  • Start queued tasks in the order they were scheduled.
  • Settle each returned promise with its own task's result.
  • Let a rejecting task fail alone, without stalling the queue.

Notes

  • Track start timestamps and drop ones older than windowMs — the sliding window shifts as entries age out.
  • Set exactly one pending timer for when the oldest timestamp expires; a per-task timer wastes resources and complicates the queue.

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +350 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.