Home Interview Design a Rate Limiter: System Design Interview Guide
Advanced 3 min · July 13, 2026

Design a Rate Limiter: System Design Interview Guide

Master the rate limiter system design interview.

N
Naren Founder & Principal Engineer

20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.

Follow
Production
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
Before you start⏱ 15-20 min read
  • Basic understanding of system design concepts (load balancing, caching, distributed systems).
  • Familiarity with Redis or similar in-memory data stores.
  • Knowledge of HTTP status codes (429 Too Many Requests).
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Rate limiters control the rate of requests to protect backend services.
  • Common algorithms: Token Bucket, Leaky Bucket, Fixed Window, Sliding Window Log, Sliding Window Counter.
  • Distributed rate limiting requires a shared store like Redis and consistency considerations.
  • Key design decisions: accuracy vs. memory, centralized vs. decentralized enforcement.
  • Interview tip: start with requirements, then algorithm choice, then scaling.
✦ Definition~90s read
What is Design a Rate Limiter?

A rate limiter is a system that controls the rate of requests to a service, preventing abuse and ensuring fair usage.

Imagine a nightclub with a capacity limit.
Plain-English First

Imagine a nightclub with a capacity limit. The bouncer (rate limiter) lets in only a certain number of people per minute. If too many try to enter, they are turned away. In computing, the rate limiter does the same for requests, preventing servers from being overwhelmed.

Rate limiting is a critical component in modern distributed systems. It protects APIs and services from abuse, ensures fair usage, and maintains system stability. In system design interviews, designing a rate limiter is a classic question that tests your understanding of algorithms, distributed systems, and trade-offs. This guide will walk you through everything you need to know: from basic algorithms like token bucket and sliding window to advanced distributed implementations using Redis. You'll also learn how to handle edge cases, common pitfalls, and how to articulate your design under interview pressure. By the end, you'll be ready to tackle any rate limiter question with confidence.

Requirements and Constraints

Before diving into algorithms, clarify the requirements. Ask your interviewer: What are we rate limiting? (e.g., API requests per user per second). What is the scale? (e.g., millions of users). Should the rate limiter be accurate or memory-efficient? Do we need to support burst traffic? Typical requirements: limit requests per user, per IP, or globally; low latency (sub-millisecond); high throughput; distributed across multiple servers; handle bursts gracefully. Non-functional: availability, durability of rate limit state, consistency (eventual vs strong).

💡Interview Tip
📊 Production Insight
In production, requirements often change. Design your rate limiter to be configurable without redeployment.
🎯 Key Takeaway
Define functional and non-functional requirements before choosing an algorithm.

Rate Limiting Algorithms

Several algorithms exist, each with trade-offs. Token Bucket: a bucket holds tokens that refill at a fixed rate. Each request consumes a token. Allows bursts up to bucket size. Leaky Bucket: requests are processed at a constant rate, with a queue for overflow. Fixed Window: count requests in a time window (e.g., 1 minute). Simple but can allow bursts at window boundaries. Sliding Window Log: keep a log of timestamps for each request; count requests in the last window. Accurate but memory-intensive. Sliding Window Counter: combine fixed window with a sliding average; more memory efficient. For interviews, token bucket and sliding window counter are popular choices.

token_bucket.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time

class TokenBucket:
    def __init__(self, capacity, refill_rate, refill_interval=1):
        self.capacity = capacity
        self.tokens = capacity
        self.refill_rate = refill_rate
        self.refill_interval = refill_interval
        self.last_refill = time.time()

    def allow_request(self, tokens=1):
        now = time.time()
        elapsed = now - self.last_refill
        if elapsed >= self.refill_interval:
            self.tokens = min(self.capacity, self.tokens + self.refill_rate * (elapsed // self.refill_interval))
            self.last_refill = now
        if self.tokens >= tokens:
            self.tokens -= tokens
            return True
        return False
📊 Production Insight
In production, use a library like Guava's RateLimiter (Java) or Redis-based implementations. Avoid reinventing the wheel.
🎯 Key Takeaway
Token bucket allows bursts and is simple to implement; sliding window counter is more memory efficient for distributed systems.

Distributed Rate Limiting with Redis

For distributed systems, a centralized store like Redis is common. Use Redis INCR with expiry to implement a sliding window counter. For token bucket, store token count and last refill timestamp in Redis. Use Lua scripting for atomic operations. Example: a sorted set for sliding window log. Considerations: Redis is single-threaded, so Lua scripts are atomic. Network latency adds overhead; consider using local counters with periodic sync for lower latency. Also handle Redis failures gracefully (e.g., fallback to local rate limiting).

redis_sliding_window.luaLUA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- Sliding window counter using sorted set
local key = KEYS[1]
local now = tonumber(ARGV[1])
local window = tonumber(ARGV[2])
local max_requests = tonumber(ARGV[3])

-- Remove old entries
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)

-- Count current requests
local count = redis.call('ZCARD', key)

if count < max_requests then
    redis.call('ZADD', key, now, now)
    redis.call('EXPIRE', key, window)
    return 1
else
    return 0
end
⚠ Atomicity
📊 Production Insight
Monitor Redis memory usage; sorted sets can grow large. Set TTL and consider using HyperLogLog for approximate counting.
🎯 Key Takeaway
Redis is the go-to for distributed rate limiting; use Lua for atomic operations.

Handling Burst Traffic and Edge Cases

Burst traffic can overwhelm a system if not handled. Token bucket naturally allows bursts up to bucket size. For sliding window, bursts at window boundaries can double the rate. Mitigation: use a smaller window or add a jitter. Edge cases: clock skew between servers (use NTP), race conditions (use locks or atomic operations), and large number of keys (use sharding). Also consider rate limiting at different layers: API gateway, application, and database. For interview, discuss how you would handle a sudden spike in traffic (e.g., viral event).

🔥Real-World Example
📊 Production Insight
Use circuit breakers to degrade gracefully when rate limiter itself becomes a bottleneck.
🎯 Key Takeaway
Design for bursts by choosing an algorithm that allows them, and handle edge cases like clock skew and race conditions.

System Design: High-Level Architecture

A typical rate limiter sits in the API gateway. For each request, extract the client identifier (user ID, IP, API key). Check the rate limit in a cache (Redis). If allowed, forward the request; else return 429. For high availability, use Redis cluster with replicas. For low latency, use local counters with periodic sync (eventual consistency). Also consider a two-tier approach: local token bucket for first line, Redis for global coordination. Discuss trade-offs: accuracy vs. performance, consistency vs. availability.

📊 Production Insight
In large systems, use a dedicated rate limiting service that can be scaled independently.
🎯 Key Takeaway
Place rate limiter at the API gateway; use Redis for distributed state; consider local caching for performance.

Interview Tips and Follow-Up Questions

In an interview, start with requirements, then propose an algorithm, then discuss scaling. Be prepared for follow-ups: How do you handle rate limiting for unauthenticated users? (Use IP address). How do you prevent a user from creating many accounts? (Use device fingerprint). How do you handle rate limit headers? (Return X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). Also discuss how to test your rate limiter (unit tests, load tests). Finally, mention monitoring and alerting (e.g., track 429 rate).

💡Common Follow-Up
📊 Production Insight
Always include rate limit headers in responses so clients can adjust their behavior.
🎯 Key Takeaway
Be ready to discuss trade-offs, edge cases, and how to handle follow-up questions about scaling and multi-tenancy.
● Production incidentPOST-MORTEMseverity: high

The Twitter API Rate Limit Meltdown

Symptom
Users and third-party apps received 429 Too Many Requests errors even with low traffic.
Assumption
The rate limiter was correctly configured based on per-user quotas.
Root cause
A bug in the sliding window implementation caused the counter to reset prematurely, effectively halving the allowed rate.
Fix
Rolled back the rate limiter code to the previous version and added comprehensive tests for edge cases.
Key lesson
  • Always test rate limiter logic with automated tests, especially around window boundaries.
  • Monitor rate limiter metrics (e.g., number of 429s) to detect anomalies.
  • Implement a circuit breaker to fall back to a safe mode if the rate limiter itself fails.
  • Use canary deployments for critical infrastructure changes.
  • Document the exact algorithm and configuration for operational teams.
Production debug guideSymptom to Action3 entries
Symptom · 01
Legitimate users getting 429 errors
Fix
Check rate limiter configuration (window size, max requests). Verify if the algorithm is correctly implemented (e.g., sliding window vs fixed window). Look for clock skew in distributed setups.
Symptom · 02
Rate limiter not blocking abusive traffic
Fix
Check if the rate limiter is bypassed (e.g., missing middleware). Verify that the key (e.g., user ID, IP) is correctly extracted. Inspect logs for missing rate limit headers.
Symptom · 03
High latency due to rate limiter
Fix
Profile the rate limiter code. If using Redis, check Redis latency and connection pool. Consider moving to a faster in-memory cache like local counters with eventual consistency.
★ Quick Debug Cheat SheetImmediate actions for common rate limiter issues.
False positives (legitimate users blocked)
Immediate action
Temporarily increase rate limit or disable rate limiter for affected users.
Commands
curl -I https://api.example.com/endpoint | grep -i 'x-ratelimit'
redis-cli get rate_limiter:user123
Fix now
Adjust window size or max requests in config.
False negatives (abusive traffic passes)+
Immediate action
Check if rate limiter is enabled for the endpoint. Verify key extraction logic.
Commands
kubectl logs -l app=api-gateway --tail=100 | grep 'rate_limit'
redis-cli keys 'rate_limiter:*' | wc -l
Fix now
Ensure rate limiter middleware is applied to all routes.
High latency+
Immediate action
Check Redis or database response times. Consider using local cache with sync.
Commands
redis-cli --latency
curl -w '%{time_total}' https://api.example.com/endpoint
Fix now
Switch to in-memory token bucket with periodic sync.
AlgorithmMemory per UserAccuracyBurst SupportComplexity
Token BucketO(1)ExactYesLow
Leaky BucketO(1)ExactNoLow
Fixed WindowO(1)ApproximateYes (at boundaries)Very Low
Sliding Window LogO(n)ExactYesHigh
Sliding Window CounterO(1)ApproximateYesMedium
⚙ Quick Reference
2 commands from this guide
FileCommand / CodePurpose
token_bucket.pyclass TokenBucket:Rate Limiting Algorithms
redis_sliding_window.lualocal key = KEYS[1]Distributed Rate Limiting with Redis

Key takeaways

1
Choose the right algorithm based on requirements
token bucket for bursts, sliding window for smoothness.
2
Use Redis with Lua scripts for atomic distributed rate limiting.
3
Always handle edge cases
clock skew, race conditions, and burst traffic.
4
Include rate limit headers in responses for client-side handling.
5
Monitor and alert on rate limiter metrics to detect issues early.

Common mistakes to avoid

3 patterns
×

Using fixed window without considering boundary bursts

×

Not handling clock skew in distributed systems

×

Storing rate limit state in a database instead of cache

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
Design a rate limiter for a social media API that handles 1 million requ...
Q02SENIOR
Compare token bucket and sliding window counter. Which one would you cho...
Q03SENIOR
How would you rate limit an API that has different tiers (free, pro, ent...
Q01 of 03SENIOR

Design a rate limiter for a social media API that handles 1 million requests per second.

ANSWER
Use token bucket with Redis for distributed state. Shard by user ID. Use Lua scripts for atomicity. Consider local cache for low latency. Return 429 with Retry-After header.
FAQ · 3 QUESTIONS

Frequently Asked Questions

01
What is the difference between token bucket and leaky bucket?
02
How do you implement rate limiting in a microservices architecture?
03
What are the trade-offs between accuracy and memory in sliding window algorithms?
N
Naren Founder & Principal Engineer

20+ years shipping production code across the stack, with years spent interviewing engineers. Drawn from code that ran under real load.

Follow
Verified
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
🔥

That's System Design Interview. Mark it forged?

3 min read · try the examples if you haven't

Previous
Design Twitter: System Design Interview
12 / 12 · System Design Interview
Next
Top SQL Interview Questions