Our goals
Rails 8 includes a built-in rate limit feature. In this article, we try to implement several use cases.
- Implementing a rate limit applicable to all traffic
- Implementing a rate limit based on user
- Implementing multiple rate limits for the same route
Use case #1
We try to set a limit like below.
class HomeController < ApplicationController
rate_limit to: 2, within: 1.minute, only: %i[index]
def index
end
end
This limits the visits to 2 per minute. If we try to access the 3rd time, our access will fail.
Such a setting is generally useful when you want to protect a specific route with the same limits for everyone. For example, you could use this to slow down the request for OTP which would be expensive if mis-used.
Use case #2
What if you want to limit the route based on the user, regardless of whether they access it from different IPs or devices?
Let's modify the code to:
class HomeController < ApplicationController
rate_limit to: 2, within: 1.minute, only: %i[index], by: -> { user_id }
def index
end
def user_id
"1"
end
end
Now, if we access as user ID 1, we get a successful response up to 2 times before it fails. If we change to user ID 2, we can immediately succeed.
Use case #3
Consider a condition where users can submit a request twice per minute and not more than four daily. To implement this, we have to set up two rate limit rules.
class HomeController < ApplicationController
rate_limit to: 2, within: 1.minute, only: %i[our_test], name: "rate1"
rate_limit to: 4, within: 1.day, only: %i[our_test], name: "rate2"
def our_test
end
end
In our test, we can access 2 in the first minute and another 2 in the second minute. Then, our daily quota is finished.
Note: A name must be given to each rule to avoid repetitive counting.