> For the complete documentation index, see [llms.txt](https://docs.lightningrails.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lightningrails.com/deploying-to-production/security/rate-limiting.md).

# Rate Limiting

Implement rate limiting using the rack-attack gem to enhance the security of your Rails application and prevent abuse. This gem helps throttle excessive requests and block abusive traffic efficiently.

Follow these step-by-step instructions to integrate **rack-attack** into your Lightning Rails app.

### **Step 1: Add the rack-attack Gem**

First, add the [**rack-attack** gem](https://github.com/rack/rack-attack) to your `Gemfile`:

```ruby
gem 'rack-attack'
```

Then, install the gem by running:

```sh
bundle install
```

### **Step 2: Configure rack-attack**

Now, configure the rate limiting rules by creating an initializer file:

```sh
touch config/initializers/rack_attack.rb
```

Open the file and add the following configuration:

```ruby
class Rack::Attack
  # Throttle requests from the same IP address to 5 requests per second
  throttle('req/ip', limit: 5, period: 1.second) do |req|
    req.ip
  end

  # Block IPs that fail authentication too many times
  Rack::Attack.blocklist('block bad IPs') do |req|
    Rack::Attack::Fail2Ban.filter("bad-ips", maxretry: 5, findtime: 1.minute, bantime: 5.minutes) do
      req.ip if req.path == "users/sign_in" || "users/sign_up" && req.post?
    end
  end

  # Allow whitelisted IPs to bypass rate limits
  safelist('allow from localhost') do |req|
    '127.0.0.1' == req.ip
  end

  # Log blocked requests
  ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, payload|
    Rails.logger.info "[Rack::Attack] Throttled: #{payload[:request].ip}" if payload[:request]
  end
end
```

This configuration:

* Limits all requests to **5 per second per IP**.
* Blocks IPs that exceed **5 failed login attempts within a minute**.
* Allows **localhost (127.0.0.1)** to bypass rate limits, you can add other IPs if needed
* Logs blocked requests for monitoring on your production server.

This last point was very usefull to me as when I suspected a bot attack, I checked the IP address and realised it was Google's IP address trying to index my site 😅

### **Step 3: Test Your Configuration**

1. **Restart Your Server**\
   Run the following command to apply the changes:

   ```sh
   shCopyEditrails restart
   ```
2. **Monitor Logs**\
   Check your Rails logs (`log/development.log`) to see if any IPs are being throttled or blocked:

   ```sh
   shCopyEdittail -f log/development.log
   ```

   If rate limits are hit, you will see messages like:

   ```
   cppCopyEdit[Rack::Attack] Throttled: 192.168.1.100
   ```
3. **Adjust Limits**
   * Modify the `limit` and `period` values to suit your needs.
   * Tweak `maxretry`, `findtime`, and `bantime` for authentication-related restrictions.
   * Add **custom rules** to protect specific endpoints like API requests.

***

### **Step 4: Deploy and Monitor**

Once tested locally, deploy your changes to production. Monitor logs and adjust limits based on real-world traffic patterns.

You can also integrate **Redis** for better performance with large-scale applications.

***

### **Final Thoughts**

By following these steps, you've successfully added rate limiting to your Rails app using **rack-attack**. This helps prevent abuse, enhance security, and optimize resource usage efficiently.

Happy coding! 🚀


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.lightningrails.com/deploying-to-production/security/rate-limiting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
