Easy Rails controller rate limiting with Rails.cache
Here's an easy trick I reach for when wanting to add simple rate limiting to an endpoint.
def special_endpoint
model = Model.find(params[:id])
cache_key = "rate_limit:mymodel:#{model.id}"
# If the key exists, we rate limit
if Rails.cache.fetch(cache_key)
return render json: { code: "too_many_requests", message: "Test webhooks can only be sent once every 20 seconds." }, status: :too_many_requests
end
# do something expensive here
# Set the key to block operations for 20 seconds
Rails.cache.write(cache_key, true, expires_in: 20.seconds)
end
This makes use of Rails.cache
to store a key for 20 seconds. If the method is hit again while the key exists, we return an error. Otherwise we allow the operation to complete.
This is a quick and easy way to add a simple rate limit to a controller. For more advanced scenarios I typically use Rack Attack.