| Users | Requests per Second (RPS) | Rate Limiter Type | Infrastructure Changes | Challenges |
|---|---|---|---|---|
| 100 users | ~500 RPS | In-process (local) rate limiting | Single microservice instance | Simple counters, low overhead |
| 10,000 users | ~50,000 RPS | Centralized rate limiter (Redis or API Gateway) | Multiple microservice instances, shared cache | Consistency, latency in shared store |
| 1,000,000 users | ~5,000,000 RPS | Distributed rate limiting with sharded stores | Multiple rate limiter clusters, load balancers | Data partitioning, synchronization, failover |
| 100,000,000 users | ~500,000,000 RPS | Hierarchical rate limiting with edge/CDN enforcement | Global distributed caches, edge nodes, multi-region | Network bandwidth, global consistency, cost |
Rate limiting in Microservices - Scalability & System Analysis
Start learning this pattern below
Jump into concepts and practice - no test required
At small scale, the first bottleneck is the in-process memory for counters in each microservice instance. As traffic grows, the bottleneck shifts to the centralized data store (like Redis) used for shared counters, which can become overwhelmed by high request rates and cause latency.
- Local Rate Limiting: Use in-memory counters for low traffic to avoid network calls.
- Centralized Store: Use Redis or Memcached with connection pooling for moderate scale.
- Sharding: Partition keys by user or API key to distribute load across multiple Redis instances.
- Hierarchical Rate Limiting: Combine edge (CDN or API Gateway) and backend limits to reduce backend load.
- Token Bucket or Leaky Bucket Algorithms: Efficient algorithms to smooth bursts and reduce storage overhead.
- Asynchronous Updates: Use approximate counters or probabilistic data structures to reduce write load.
- Load Balancing: Distribute requests evenly to rate limiter clusters to avoid hotspots.
- At 10,000 users with 50,000 RPS, Redis needs to handle ~50,000 ops/sec, which is near a single Redis instance limit; requires sharding or clustering.
- Each request counter uses a few bytes; for 1M users, storage for counters can reach several GBs in Redis.
- Network bandwidth for rate limiter calls grows with RPS; at 5M RPS, requires multiple high-throughput network links.
- CPU usage on microservices increases with local rate limiting logic; offloading to dedicated rate limiter services can reduce this.
Start by clarifying the scale and traffic patterns. Discuss simple local rate limiting first, then explain how centralized stores become bottlenecks. Describe sharding and hierarchical approaches. Emphasize trade-offs between accuracy, latency, and cost. Use real numbers to show understanding of limits and solutions.
Your database handles 1000 QPS for rate limiting counters. Traffic grows 10x to 10,000 QPS. What do you do first?
Answer: Introduce caching or sharding to distribute load. For example, add Redis read replicas or partition counters by user ID to multiple Redis instances to avoid overloading a single database.
Practice
rate limiting in microservices?Solution
Step 1: Understand the concept of rate limiting
Rate limiting is designed to restrict the number of requests a user or client can send to a service within a certain time frame.Step 2: Identify the main goal of rate limiting
The main goal is to prevent overload and abuse by controlling request frequency, not to speed up services or store data.Final Answer:
To control how many requests a user can make in a given time -> Option AQuick Check:
Rate limiting = Control request count [OK]
- Confusing rate limiting with load balancing
- Thinking rate limiting speeds up the service
- Mixing rate limiting with data storage
Solution
Step 1: Understand fixed window rate limiting logic
Fixed window rate limiting counts requests in a fixed time window (e.g., 1 minute) and blocks if the count exceeds the limit.Step 2: Match the correct condition for allowing or blocking
If requests exceed 100 in the last minute, block; otherwise, allow. if requests_in_last_minute > 100 then block else allow matches this logic exactly.Final Answer:
if requests_in_last_minute > 100 then block else allow -> Option CQuick Check:
Fixed window limit = block if over limit [OK]
- Using wrong time window (hour instead of minute)
- Reversing the condition (blocking when under limit)
- Allowing requests when they should be blocked
bucket_capacity = 5
refill_rate = 1 token per second
current_tokens = 3
request_tokens = 2
if current_tokens >= request_tokens:
current_tokens -= request_tokens
allow request
else:
block requestWhat happens if a request for 4 tokens arrives immediately?
Solution
Step 1: Check current tokens against requested tokens
Current tokens are 3, request needs 4 tokens, which is more than available.Step 2: Determine if request is allowed or blocked
Since current tokens (3) < request tokens (4), the request is blocked.Final Answer:
Request is blocked because not enough tokens -> Option DQuick Check:
Tokens < request = block [OK]
- Allowing request when tokens are insufficient
- Ignoring token count and refill rate
- Assuming tokens can go negative
Solution
Step 1: Understand sliding window rate limiter behavior
Sliding window requires accurate tracking of request timestamps across all servers to count requests correctly.Step 2: Identify issue with multiple servers and no shared state
If servers do not share state, each counts requests independently, causing incorrect blocking even if total requests are under limit.Final Answer:
The service has too many servers without shared state -> Option BQuick Check:
Multiple servers need shared state for sliding window [OK]
- Blaming slow user requests
- Assuming rate limit is too high causes blocking
- Ignoring distributed state issues
Solution
Step 1: Analyze scalability needs for 10 million users
A centralized database (Use a centralized fixed window counter stored in a single database) or storing every timestamp centrally (Use a sliding window log storing every request timestamp centrally) will cause bottlenecks and high latency.Step 2: Evaluate distributed token bucket with local caches
Distributed token buckets with local caches reduce central load and sync periodically, balancing accuracy and scalability well.Step 3: Consider client-side rate limiting
Client-side (Use client-side rate limiting without server checks) is unreliable as clients can bypass limits.Final Answer:
Use distributed token buckets with local caches and periodic sync -> Option AQuick Check:
Distributed token bucket = scalable + accurate [OK]
- Choosing centralized storage causing bottlenecks
- Relying only on client-side limits
- Storing all request logs centrally causing overload
