Explain rate limiting algorithms.
Skip to solutionKEEP THE
mediumSystem Design
How would you design a rate limiter?
550 views
01
Understand the problem
rate-limiting
02
Attempt it yourself
Sketch your approach before reading the solution — that's what interviews test.
Nudge consolestandby
Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.
03
Study the solution
Designing a Rate Limiter
Target Audience: Junior & Senior Software Engineers preparing for System Design Interviews — no prior system design knowledge assumed. Difficulty: Easy to Medium
How to read this doc: Every concept is explained in plain language first. Right after, you'll see a callout like `�
Solution ready — 2 min read
Classified // press E to declassify
04
Read the code
Fixed Window Counter rate limiter
Run Playgroundclass FixedWindowCounter {
constructor(limit, windowSize) {
this.limit = limit;
this.windowSize = windowSize;
this.currentWindowId = null;
this.count = 0;
}
allow(now) {
const windowId = Math.floor(now / this.windowSize);
if (windowId !== this.currentWindowId) {
this.currentWindowId = windowId;
this.count = 0;
}
if (this.count < this.limit) {
this.count += 1;
return true;
}
return false;
}
}
const limiter = new FixedWindowCounter(3, 10);
const times = [0, 0, 0, 0, 9, 10, 10, 10, 10];
console.log(times.map((t) => limiter.allow(t)));Sliding Window Log rate limiter
class SlidingWindowLog {
constructor(limit, windowSize) {
this.limit = limit;
this.windowSize = windowSize;
this.log = [];
}
allow(now) {
const cutoff = now - this.windowSize;
this.log = this.log.filter((t) => t > cutoff);
if (this.log.length < this.limit) {
this.log.push(now);
return true;
}
return false;
}
}
const limiter = new SlidingWindowLog(3, 10);
const times = [0, 0, 0, 0, 5, 10, 11];
console.log(times.map((t) => limiter.allow(t)));Sliding Window Counter rate limiter
Run Playgroundclass SlidingWindowCounter {
constructor(limit, windowSize) {
this.limit = limit;
this.windowSize = windowSize;
this.currentWindowId = null;
this.currentCount = 0;
this.previousCount = 0;
}
allow(now) {
const windowId = Math.floor(now / this.windowSize);
if (windowId !== this.currentWindowId) {
if (this.currentWindowId !== null && windowId === this.currentWindowId + 1) {
this.previousCount = this.currentCount;
} else {
this.previousCount = 0;
}
this.currentCount = 0;
this.currentWindowId = windowId;
}
const fraction = (now % this.windowSize) / this.windowSize;
const estimated = this.currentCount + this.previousCount * (1 - fraction);
if (estimated < this.limit) {
this.currentCount += 1;
return true;
}
return false;
}
}
const limiter = new SlidingWindowCounter(5, 10);
const times = [0, 0, 0, 0, 0, 0, 15, 15, 15, 15];
console.log(times.map((t) => limiter.allow(t)));Token bucket rate limiter
Run Playgroundclass TokenBucket {
constructor(capacity, refillRate) {
this.capacity = capacity;
this.refillRate = refillRate; // tokens added per tick
this.tokens = capacity;
this.lastRefill = 0;
}
allow(now) {
const elapsed = now - this.lastRefill;
this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillRate);
this.lastRefill = now;
if (this.tokens >= 1) {
this.tokens -= 1;
return true;
}
return false;
}
}
const bucket = new TokenBucket(5, 1.0);
const results = [];
for (let i = 0; i < 6; i++) results.push(bucket.allow(0));
for (let i = 0; i < 4; i++) results.push(bucket.allow(3));
console.log(results);Leaky Bucket rate limiter
Run Playgroundclass LeakyBucket {
constructor(capacity, leakRate) {
this.capacity = capacity;
this.leakRate = leakRate;
this.queueLevel = 0;
this.lastLeak = 0;
}
allow(now) {
const elapsed = now - this.lastLeak;
this.queueLevel = Math.max(0, this.queueLevel - elapsed * this.leakRate);
this.lastLeak = now;
if (this.queueLevel < this.capacity) {
this.queueLevel += 1;
return true;
}
return false;
}
}
const limiter = new LeakyBucket(3, 1.0);
const times = [0, 0, 0, 0, 2, 2, 2];
console.log(times.map((t) => limiter.allow(t)));05
Join the discussion
Discussion (0)
Sign in to join the discussion.
No responses yet. Be the first to share what you think.
Transmission complete // awaiting log
KEEP THE
STREAK ALIVE.
Dossier 27 of 99 decoded in the System Design track. One more won't hurt.