# 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.