few options
Now and then there are cases where in you want to implement a rate limiter.You could have used nginx or other webservers but the functionality is limited or if that is fine for your use case.
For example in nginx you can have only per second or per minute rate limit and they don’t care about the response status for the particular request i.e rate limit is enforced a particular endpoint in all cases.
So you might implement in your language of choice using redis.Here is the basic one from the docs
FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
MULTI
INCR(keyname)
EXPIRE(keyname,10)
EXEC
current = RESPONSE_OF_INCR_WITHIN_MULTI
IF current > 10 THEN
ERROR "too many requests per second"
ELSE
PERFORM_API_CALL()
END
In the above code, one point that we need to note is that we need to check if the request count is greater than the threshold once we do the increment.
See the below example, here we are first checking if key is present else we are incrementing and setting an expiry.
If we have lets say 4 application instances and all of them see current as 9 and which is possible as all the instances might see do a get query at same time before either one increments, then we would pass all of the requests and by effect we would have allowed 13 requests.So the below pattern has to be avoided.
FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
current = get keyname
IF NOT current THEN
MULTI
INCR(keyname)
EXPIRE(keyname,10)
EXEC
END
IF current > 10 THEN
ERROR "too many requests per second"
ELSE
PERFORM_API_CALL()
incr key
END
Incase you have looked at this article, there is one fine point.
>
MULTIOK
> INCR [user-api-key]:[current minute number]
QUEUED
> EXPIRE [user-api-key]:[current minute number] 59
QUEUED
>
EXEC
OK
Suppose api key is abc and current minute is 30
redsi key → abc:30, So we increment the counter at this key and also expire by 59 seconds.SO if a request from an ip comes at 59 seconds past 30th minute, the key for 30th minute will be live in 31st minute.
Though the abc:30 key will not be used in the 31st minute as we use the key abc:31 in the 31st minute but the key abc:30 might be hanging in there for sometime in the 31st minute as well.
So that’s just a finer point.
The below looked interesting