Rails ships a built-in rate limiter. In a sessions controller, add rate_limit to: 10, within: 3.minutes, only: :create and repeated sign in attempts from the same client are throttled. It slows brute force and credential stuffing but does not replace strong passwords, lockout policy or monitoring.
Why logins need throttling
The Rails security guide describes brute force attacks as trial and error against login credentials. Attackers pair a list of usernames with a dictionary. The guide also points at forgot password pages, which often reveal whether an email address exists, letting an attacker build a list of valid accounts first. Its advice includes rate limiting, generic error messages, and possibly a CAPTCHA.
The one line
class SessionsController < ApplicationController
rate_limit to: 10, within: 3.minutes, only: :create
end
That is the example from the guide. It allows ten requests in three minutes to the create action, then responds with an error until the window passes. Apply the same idea to password reset requests, signup, one time code checks and any endpoint that sends email or text messages.
Choosing numbers
| Endpoint | Starting point | Reason |
|---|---|---|
| Sign in | A handful per few minutes per client | Humans mistype a few times |
| Password reset request | Lower | Avoid email floods |
| One time code entry | Very low | Short codes are guessable |
| Signup | Low per client | Slow automated account creation |
These are judgement calls, not rules from the documentation. Tune from your logs and your users.
Steps
- Identify every endpoint that accepts credentials or triggers messages.
- Add
rate_limitto each, with tighter numbers for the riskiest. - Return the same message for unknown users and wrong passwords.
- Add per account limits as well as per client limits, because an attacker can rotate addresses.
- Log throttled requests and alert on spikes.
- Test behind your load balancer, so the client address Rails sees is the real one.
Step 6 is where teams get caught. If every request appears to come from the proxy, one noisy user can lock out everyone, or the limit never triggers per person.
What it will not do
A per client counter does not stop a slow attack spread across many addresses, and it does not know which accounts matter most. Combine it with multi factor authentication, breached password checks and account recovery that does not leak which users exist. Rate limiting is a speed bump, which is still worth having.
Where counters live
A rate limiter needs somewhere to store counts. In a multi server deployment, make sure the store is shared, or each server counts separately and the effective limit is multiplied. Check your cache configuration in production, and test the limit by sending a burst of requests against staging. Also decide what the user sees when throttled, and keep that message generic.
Quick check
Is rate_limit enough for brute force protection?
It helps a lot against simple attacks. Add strong password rules, generic errors and monitoring for distributed attempts.
Which actions should I limit?
Sign in, password reset, signup, code verification and anything that sends a message.
Safeguard's policy gates can help enforce that endpoints like these are reviewed before release. A free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.