We have the following rate limiting algorithms.
By comparing the above algorithm and their cons / pros, we decide to use the token bucket algorithm for our rate limiter as it is easy implementation and able to handle burst traffic. In actual practice, the algorithm can be dynamic to fit different use cases.
For Rate limiter, API is not necessary needed for it
and generally if the requests received by the application, we would take the userId and ip address to validate whether it reached the limit or not
prefer using key-value store such as Redis for current design as it stores data in memory and easily to populate and use, also it would provide fast reads as everything stored in memory/
For data stored in Redis, we can use
tableName: RequestCounts
key: rate_limiter:userId:ipAddress
value: {
"count" : "3",
"requestTime" : currentMillis
}
In terms of deploying in the distributed system, we can have Redis Cluster which have at lease 3 masters and 3 followers to ensure high available, fault tolerance and best performance.
The clients (web browser / mobile app) sends a request to rate limiter middleware.
the rate limiter middleware decides if the request should be limited
if limited, discard the request.
if not limited, pass the request to the API servers.
why use API Gateway instead of Load Balancer
need an application-level component that can run that logic per request. A simple load balancer can’t interpret your rate-limit rules, hit Redis, or return a custom 429 payload—it can only proxy TCP/HTTP.
The rate limiting rules can be stored in disk as config files. For example:
{
"rules": [
"rate_limit": {
"unit": "minute",
"requests_per_unit": 5,
"burst_capacity": 10 # for token-bucket bursts
},
"algorithm": "token_bucket", # or fixed_window, sliding_window_log, etc.
}
]
}
Two problems:
GET, INCR, EXPIRE) into one atomic operationTry to discuss as many failure scenarios/bottlenecks as possible.
Hard rate limiting vs soft rate limiting: