Authentication endpoints attract automation because each request can test credentials, probe account state, or trigger expensive verification work. Rate controls reduce the speed and value of this abuse, but a single requests-per-minute limit is rarely enough.
A useful design combines several signals and responses. The objective is to make abusive behaviour slower and noisier while keeping legitimate users able to recover from mistakes, shared networks, and temporary failures.
Protect the whole authentication surface
Login is only one part of authentication. Review every endpoint that can verify, change, or recover identity state, including:
- password login;
- multi-factor authentication challenges;
- password reset requests and token verification;
- email or phone verification;
- account recovery;
- magic-link requests;
- device enrollment.
Attackers often move to the least protected path. Strong login throttling provides limited value if a recovery endpoint accepts unlimited attempts.
Avoid relying on one identifier
An IP-only limit is simple, but attackers can distribute requests across many addresses. It can also punish legitimate users who share a public address through an office, mobile carrier, school, or VPN.
An account-only limit has the opposite weakness: an attacker who knows a victim’s username may deliberately exhaust the allowance and prevent the victim from signing in.
Use multiple dimensions where practical, such as source address, normalized account identifier, device or session signals, action type, and aggregate service traffic. Different dimensions can have different thresholds. The value comes from making one attacker-controlled signal insufficient to bypass or weaponize the control.
Normalize identifiers before counting
Logically equivalent identifiers should not receive separate counters. If authentication treats email addresses case-insensitively, for example, the rate-control key should follow the same rule.
Apply normalization consistently with the identity system. Do not invent transformations that change the meaning of valid usernames.
Prefer progressive friction to long lockouts
Long account lockouts can turn a defense into a denial-of-service mechanism. An attacker can intentionally submit bad credentials until a victim is locked out.
Progressive responses are usually safer. As suspicious attempts accumulate, introduce increasing delay, require additional verification, temporarily restrict a source, or apply a short cooldown. The response should reflect the action: a failed password attempt and a failed second-factor challenge after a correct password are different security events.
Avoid implementing delays by holding server workers asleep. Enforce cooldowns with timestamps, counters, gateways, queues, or other mechanisms that do not unnecessarily consume application capacity.
Protect expensive operations separately
Counting only failed logins misses cost-amplification attacks. Sending email or SMS, invoking an external identity provider, calculating expensive password hashes, or creating recovery records can consume resources before an authentication result exists.
Apply limits before expensive downstream work when possible. Notification flows should also limit repeated sends to the same destination so an attacker cannot use the service to flood a user with messages.
Do not create account-enumeration signals
Rate limiting should not reveal whether an account exists.
If a reset endpoint returns one response for a known account and a visibly different throttling response for an unknown account, attackers may use the difference to enumerate users. Similar leaks can appear in status codes, response bodies, headers, or large timing differences.
Where account existence is sensitive, keep externally visible behaviour reasonably consistent. Internally, account-aware counters can still be applied after identity lookup.
Observe successful attempts too
A successful login should not erase every sign of suspicious activity. Credential-stuffing campaigns can contain valid credentials, so a source that tries many accounts and succeeds occasionally may still be abusive.
Track relevant patterns across successes and failures. This can reveal one source targeting many accounts or one account receiving attempts from many sources. Store only signals needed for a defined security purpose, protect them appropriately, and follow applicable privacy and retention requirements.
Separate bursts from sustained abuse
Legitimate clients sometimes generate short bursts because of retries, reloads, password managers, or unstable networks. Attackers may instead sustain a lower request rate for hours.
Using more than one time window can address both patterns. A short window controls bursts while a longer window limits sustained automation. Token-bucket, leaky-bucket, fixed-window, and sliding-window approaches can all work when their behaviour is understood.
Review the resulting security properties:
- How large a legitimate burst can pass?
- How quickly does capacity recover?
- Can requests around a window boundary exceed the intended rate?
- Are counters consistent across application instances?
- What happens when the counter store is unavailable?
The answers matter more than the name of the algorithm.
Define failure behaviour explicitly
Distributed controls often depend on a shared datastore or gateway, and that dependency can fail.
Failing open preserves availability but temporarily weakens abuse resistance. Failing closed protects the operation but may prevent legitimate authentication during an infrastructure incident. Choose deliberately based on the protected action and expected impact.
A mixed strategy may be appropriate. An application can preserve a conservative local limit when shared counters are unavailable while treating especially sensitive recovery actions more restrictively.
Return useful responses
For HTTP services, 429 Too Many Requests is appropriate when a request policy has been exceeded. A Retry-After header can help well-behaved clients back off when exposing the cooldown is acceptable.
Do not expose internal scoring rules or exact account-specific thresholds. Legitimate users need enough information to recover, not a description of the detection model.
Log enough to tune the control
Without telemetry, teams cannot tell whether thresholds stop abuse or mainly frustrate users. Record security-relevant information such as the action, outcome category, class of limit reached, timestamp, protected account identifier, permitted source signals, and request correlation ID.
Never log passwords, one-time codes, reset tokens, session secrets, or other authentication credentials.
Monitor aggregate patterns as well as individual blocks. A surge in throttled traffic, many accounts targeted from one source, or one account targeted from many sources can represent different attack patterns.
Test realistic edge cases
Verify that counters work across application instances, identifiers are normalized consistently, cooldowns expire correctly, and recovery paths remain usable. Test shared-network scenarios and distributed attempts. Confirm that an attacker cannot keep a victim locked out indefinitely by continuously generating failures.
Also test operational failures such as counter-store latency, unavailable dependencies, clock differences, deployment changes, and configuration rollback.
Use rate controls as one layer
Rate limiting slows automated abuse, but it does not make weak authentication safe. A slow credential-stuffing attack can still succeed when users reuse compromised passwords.
Combine rate controls with stronger defenses such as multi-factor authentication, secure password storage, safe account recovery, session protection, and monitoring for suspicious authentication activity.
A practical review should confirm that every identity-sensitive endpoint has an abuse-control strategy, limits cannot be easily weaponized against a victim, expensive operations are protected, account-enumeration signals are minimized, failure behaviour is defined, and telemetry supports investigation without recording credentials.
Good authentication rate controls are deliberately balanced barriers. They tolerate normal human mistakes and network realities while making automation slower, noisier, and more costly. Layered controls achieve that balance more reliably than a single global limit or a lockout rule that attackers can turn against users.