Source: https://jessewaites.com/blog/post/how-to-rate-limit-your-ruby-on-rails-controllers

# How to Rate Limit Your Ruby On Rails Controllers

*September 20, 2025*

Rails 8 introduced a new `rate_limit` feature for controllers, which makes throttling requests much easier to implement and manage than that was back in the day. Instead of relying on middleware or third-party gems, you can now declare rate limits directly in your controllers and centralize how you respond when clients exceed them 🙂

A common pattern is to define a base rule in a parent controller. In this example, `ApiController` limits requests by IP to five per minute:

```
class ApiController < ApplicationController
  rate_limit to: 5, within: 1.minute, by: :ip, with: -> { handle_rate_limit }

  private

  def handle_rate_limit(message: "Server is busy. Please try again later.")
    redirect_to busy_path(error: message)
  end
end

```

The `handle_rate_limit` method provides a centralized place to decide what happens when the limit is reached. Instead of sprinkling custom responses across multiple controllers, you have one consistent handler.

Controllers that inherit from `ApiController` can declare their own limits without losing the shared handler. For example, a `UsersController` might restrict signup attempts by domain:

```
class UsersController < ApiController
  rate_limit to: 1000, within: 10.seconds,
    by: -> { request.domain },
    with: -> { handle_rate_limit(message: "Too many signups on your domain.") },
    only: :create

  def create
    # signup logic
  end
end

```

Here, the base IP-based rule still applies to all actions, but the `create` action has an additional domain-based limit with its own message. This flexibility means you can apply different throttling strategies depending on context.

Finally, the `BusyController` provides a clean, consistent response:

```
class BusyController < ApplicationController
  def index
    render json: { error: params&#91;:error] }, status: :too_many_requests
  end
end

```

This ensures clients always receive a proper `429 Too Many Requests` response with an error message. You could extend this later with logging, alerting, or custom JSON structures without touching every controller.

By combining `rate_limit` with a centralized handler and a dedicated controller for responses, Rails 8 turns rate limiting into a straightforward solution. You get both flexibility and consistency while keeping your controllers focused on their core purpose.
