# auth.login-throttle
Before checking a password, ask whether this account may try at all:
```
decision = loginThrottle(recentFailures, now, {maxAttempts: 5, windowSeconds: 900, lockoutSeconds: 900})
if not allowed: answer 429 with Retry-After: retryAfterSeconds (and do not check the password)
else: check it; on failure, record `now` as another failure
```
The application stores the times of failed logins per account (per
normalised email, so an attacker cannot dodge the count by changing case) and
passes them in with the current time. The capability keeps no state and reads
no clock.
**The rule.** Failures are replayed in time order. When `maxAttempts`
failures fall within `windowSeconds` of each other (each within the window
ending at the latest), the account is locked from that failure for
`lockoutSeconds`, and the count starts again from zero. Failures recorded
while locked do not count and do not extend the lockout (the application
should not be recording them, since it does not check the password then).
A lockout ends exactly at `lockedUntil`: at that second the account is
allowed again, with its full allowance, because the failures that caused the
lockout have been paid for. Failures stamped after `now` (clock skew between
servers) are ignored.
`remainingAttempts` is how many more failures the account can have before it
is locked, counting only failures still inside the window; a login form may
show it ("2 attempts left"), though many sites prefer not to.
**Settings.** 5 attempts in 15 minutes and a 15-minute lockout
(`{5, 900, 900}`) is a common, humane default: it stops online guessing
(at most 480 guesses a day) while a forgetful person is inconvenienced for
minutes, not locked out until support replies. NIST SP 800-63B-4 section 3.2.2
requires limiting consecutive failed attempts to no more than 100, so any
setting here meets that; OWASP's Authentication Cheat Sheet discusses the
trade-off with denial of service against known usernames.
A successful login does not clear earlier failures here; if the application
wants that, it deletes the stored failures on success.
Sources: NIST SP 800-63B-4, section 3.2.2, Rate Limiting (Throttling)
(https://pages.nist.gov/800-63-4/sp800-63b.html); OWASP Authentication Cheat
Sheet, Account Lockout
(https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html);
RFC 9110 section 10.2.3, Retry-After.