Upcoming changes in Rails rate limiter
Rails 7.2 introduced a built-in rate limiting and now the next version of Rails has a few nice improvements lined up.
Historically we would use rack-attack for rate limiting, but Rails 7.2 introduced a built-in rate limiter:
class SignupController < ApplicationController
rate_limit to: 5, within: 1.minute
def create
render plain: "Signed up"
end
endIn the upcoming Rails 8.2, two new features will be quite useful. I had mentioned them in my previous blog on rate limiting, but let us look at them in detail here.
Dynamic duration and window
Previously the duration to: and window within: parameters only accepted fixed values. Now they can be a callable (method name, proc or lambda) allowing dynamic values:
class EmployeesController < ApplicationController
rate_limit to: :max_requests, within: :max_duration
def create
render plain: "Employee created"
end
private
def max_requests
current_user.admin? ? 1000 : 5
end
def max_duration
current_user.admin? ? 1.hour : 1.minute
end
endThis allows us to change the rate limit based on business logic.
Duck-typing cache-key object
Default rate limit is on remote_ip. Now you can pass object which responds to cache_key:
class User < ApplicationRecord
def cache_key
"user/#{id}"
end
endclass ReportsController < ApplicationController
rate_limit to: 20, within: 1.minute, by: -> { current_user }
endThis implements a per-user rate limit.
All the code code and tests can be found in this gist.
Available for hire
I am open to new roles. I bring 13 years of backend engineering experience, primarily in Ruby on Rails, with additional experience in TypeScript, Node.js, and Elixir.
Please have a look at my services.
Leads and referrals welcome — tejasbubane@gmail.com