Safeguard
Security Guides•

How do you rate limit logins in Rails with the built-in rate_limit?

Rails has a built-in rate_limit controller method. One line throttles login or password reset attempts. See usage, limits, and what else to add.

Safeguard Security Team
3 min read

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

EndpointStarting pointReason
Sign inA handful per few minutes per clientHumans mistype a few times
Password reset requestLowerAvoid email floods
One time code entryVery lowShort codes are guessable
SignupLow per clientSlow automated account creation

These are judgement calls, not rules from the documentation. Tune from your logs and your users.

Steps

  1. Identify every endpoint that accepts credentials or triggers messages.
  2. Add rate_limit to each, with tighter numbers for the riskiest.
  3. Return the same message for unknown users and wrong passwords.
  4. Add per account limits as well as per client limits, because an attacker can rotate addresses.
  5. Log throttled requests and alert on spikes.
  6. 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.