OTP expiration is the window during which a one-time password remains valid after delivery. OTP rate limiting is the mechanism that restricts how many codes a user can request or attempt within a given period. Together, they determine whether your verification flow is secure, usable, or an open door for attackers.
Get the balance wrong and you either lock out legitimate users or hand attackers unlimited guesses. This guide covers the OTP expiration time best practices, rate-limiting thresholds, and lockout policies that keep your verification system tight — with use-case-specific recommendations for login, payments, fintech KYC, and mobile money transactions.
Quick-Reference: OTP Expiration and Rate Limiting by Use Case
| Use Case | Recommended Expiry | Max Attempts | Cooldown After Limit |
|---|---|---|---|
| Login / 2FA | 2 — 5 min | 3 — 5 | 15 min |
| Payment Confirmation | 3 — 5 min | 3 | 30 min |
| Account Recovery | 10 — 15 min | 3 | 60 min |
| Device Registration | 5 — 10 min | 3 | 30 min |
| Email Verification | 15 — 30 min | 5 | 60 min |
| Mobile Money (MoMo) | 3 — 5 min | 3 | 30 min |
| Fintech KYC | 5 — 10 min | 3 | 60 min |
| Banking Transaction | 60 — 90 sec | 2 — 3 | 30 min |
Each row explained in detail below, including the reasoning behind every threshold.
How Long Should an OTP Be Valid?
The right OTP expiration window depends on the use case, the delivery channel, and the network conditions your users face.
A login OTP on a fast network might need only 60 seconds. A fintech KYC verification — where the user is uploading identity documents between receiving and entering the code — needs significantly more time.
Standard Use Cases
Login and two-factor authentication: 2 — 5 minutes. The user is already at the input screen. They receive the code, type it, and move on. Shorter windows reduce the attack surface.
Payment and transaction confirmation: 3 — 5 minutes. The user needs time to review transaction details — amount, recipient, account — before entering the code. Rushing this step increases errors and abandoned transactions.
Account recovery: 10 — 15 minutes. Recovery flows often require switching devices or checking a secondary email. Longer windows prevent unnecessary retries without meaningfully increasing risk, since recovery tokens are typically single-use.
Device registration: 5 — 10 minutes. One-time setup flows tolerate higher friction. The security benefit of binding a new device justifies a slightly longer window.
Email verification: 15 — 30 minutes. Email delivery delays are unpredictable. Short windows generate frustration and repeated send requests.
Africa-Context OTP Expiration Windows
If you are building for markets in Ghana, Nigeria, Kenya, or South Africa, standard OTP expiration windows may not account for real-world conditions.
Mobile money (MoMo) transaction OTP: 3 — 5 minutes. Mobile money users on MTN MoMo or Telecel Cash often navigate USSD menus before entering a confirmation code. USSD session navigation takes longer than a web form. A 60-second window that works for a banking app login will time out mid-flow for a MoMo user dialing through menu layers.
Fintech KYC verification: 5 — 10 minutes. Fintech onboarding in Ghana and Nigeria typically requires uploading ID documents — Ghana Card, BVN validation, or passport scans — alongside OTP verification. The user is switching between camera, file picker, and OTP input. A 2-minute window forces restarts. For more on OTP for fintech banking, see the dedicated guide.
Banking transaction approval: 60 — 90 seconds. High-value, real-time transactions in African mobile banking apps demand tight windows. Mobile money transactions are irreversible — once funds leave, recovery is manual and uncertain. The short expiry window is a deliberate security constraint.
SMS delivery latency matters. African mobile networks may add 15 — 45 seconds of delivery delay compared to 5 — 10 seconds on US or European networks. Factor this into your OTP expiration calculation. A 60-second OTP that arrives at the 40-second mark gives the user 20 seconds to read and type — not enough.
What Does NIST Say About OTP Expiration?
The existing guidance from NIST SP 800-63B-4 is frequently misquoted across developer blogs and documentation. Many sources claim “NIST recommends no longer than 10 minutes.” That specific recommendation does not appear in the standard.
What NIST actually requires: time-based OTPs must have a defined lifetime determined by expected clock drift, network delay, and claimant entry time. The verifier must implement rate-limiting on consecutive failed attempts. The standard prescribes a methodology for calculating appropriate lifetime — not a fixed cap.
NIST SP 800-63B-4 also classifies SMS OTP as a “restricted authenticator” due to known vulnerabilities including SIM swap and SS7 interception. This does not mean SMS OTP is prohibited. It means systems relying on SMS OTP should implement compensating controls — and expiration windows plus rate limiting are two of the most important.
The practical takeaway: calculate your OTP lifetime based on your actual delivery latency, your users’ expected entry speed, and any clock synchronization factors. A blanket “10 minutes” is neither required by NIST nor appropriate for most use cases.
How Many OTP Attempts Should Be Allowed Before Lockout?
Rate limiting controls how many times a user can attempt an OTP before the system intervenes. Without it, a 6-digit OTP gives an attacker 1,000,000 possible combinations to try. With rate limiting, they get three to five.
The OTP best practices for attempt limits follow a layered approach.
Per-Phone-Number Limits
Limit OTP sends by the recipient phone number — not just by user account. This prevents attackers from flooding a phone number with codes, which both degrades the user experience and inflates your SMS costs.
Recommended thresholds:
- Send limit: 3 — 5 OTPs per phone number per hour
- Attempt limit: 3 — 5 wrong-code entries per OTP
- Cooldown: 15 — 30 minutes after hitting the limit
Per-IP Rate Limits
Layer IP-based rate limiting on top of phone-number limits. This catches automated attacks that rotate phone numbers but originate from the same source.
- Send limit: 10 — 20 OTP requests per IP per hour
- Burst protection: No more than 3 requests per IP in any 60-second window
Account-Level Lockout
After repeated failures across multiple OTPs, lock the account and require an alternative recovery method.
- Threshold: 10 total failed attempts across all OTPs within 24 hours triggers account lockout
- Recovery: Require identity verification through a secondary channel (email, support ticket, in-person)
OTP Rate Limiting and SMS Pumping Prevention
Rate limiting is your first defense against SMS pumping fraud — artificially inflated traffic that generates fraudulent SMS charges. SMS pumping fraud costs the telecom industry billions annually. According to the CFCA, global telecom fraud losses reached an estimated $38.95 billion in 2023, a 12% increase from 2021.
Unprotected OTP endpoints are a primary target. Without per-number and per-IP limits, an attacker can trigger thousands of OTP sends per minute — each one generating an SMS charge on your account. If you are evaluating providers that handle rate limiting natively, compare OTP API providers for built-in fraud controls.
Need an OTP API with built-in expiration and rate limiting? Arkesel’s Phone Number Verification handles OTP delivery, retry logic, and fraud controls out of the box — explore the developer docs to integrate.
OTP Rate Limiting Implementation Patterns
Two common approaches work for OTP-specific rate limiting.
Token bucket assigns each user or phone number a fixed number of tokens (attempts). Each request consumes a token. Tokens refill at a set rate. This approach handles bursty traffic well — a user who needs to re-request an OTP gets immediate access, but sustained abuse is blocked.
Sliding window tracks requests within a rolling time period. More predictable than token bucket, but less forgiving of legitimate retry bursts.
For most OTP implementations, token bucket with exponential backoff on resend gives the best balance of security and usability.
Distinguish Error Types in Your OTP Flow
Your rate limiting logic should differentiate between wrong-code and expired-code errors. A user who enters an expired code is not making an attack attempt — they need a new code. Counting expired entries against their attempt limit creates unnecessary friction.
- Wrong code: Decrement remaining attempts. Show: “That code doesn’t match. You have 2 attempts remaining.”
- Expired code: Auto-send a new code (within send rate limits). Show: “This code has expired. We’ve sent a new one to your phone.”
- Rate limited: Show: “Too many attempts. Please wait 15 minutes before requesting a new code.”
For deeper implementation guidance and code examples, see the OTP API setup tutorial. If you run into errors during integration, the OTP API troubleshooting guide covers the most common issues.
Best Fallback Methods When OTP SMS Fails
SMS delivery is not guaranteed. Network congestion, carrier filtering, and number portability issues can all prevent delivery. Your OTP system needs a fallback path.
Channel fallback sequence: SMS first, then voice call, then email. Each step widens the delivery window but also changes the security profile. Voice OTP delivery reaches users whose SMS is blocked or delayed — critical in African markets where SMS routing through aggregators occasionally introduces delays.
For a detailed comparison of delivery channels, see SMS vs authenticator app vs email OTP.
Retry with backoff: If the first SMS does not arrive within 30 seconds, offer a resend button — but enforce exponential backoff on retries. First retry at 30 seconds, second at 60 seconds, third at 120 seconds.
Communicate clearly. When delivery fails, tell the user what is happening and what to do next. “Didn’t receive your code? Wait 30 seconds and we’ll send another” is actionable. “An error occurred” is not.
OTP Expiration and Rate Limiting Checklist
Use this checklist before shipping your OTP verification flow:
- OTP expiration window is set per use case (not a blanket default)
- SMS delivery latency is factored into the expiration window
- Per-phone-number send limits are in place (3 — 5 per hour)
- Per-phone-number attempt limits are in place (3 — 5 per OTP)
- Per-IP rate limiting is layered on top (10 — 20 per hour)
- Expired-code and wrong-code errors are handled differently
- Account-level lockout triggers after 10 cumulative failures in 24 hours
- Fallback delivery channel is configured (voice or email)
- Error messages are specific: wrong code vs expired vs rate limited
- OTPs are single-use and invalidated after successful verification
For broader OTP security patterns — including code length, hashing, and transport encryption — see the OTP API integration guide.
FAQ
How long should an OTP be valid? It depends on the use case. Login OTPs: 2 — 5 minutes. Payment confirmations: 3 — 5 minutes. Account recovery: 10 — 15 minutes. Mobile money transactions: 3 — 5 minutes. Banking approvals: 60 — 90 seconds. Always factor in SMS delivery latency for your target market.
How many OTP attempts should be allowed before lockout? 3 — 5 wrong-code attempts per individual OTP. After 10 cumulative failures across all OTPs within 24 hours, lock the account and require identity verification through a secondary channel.
What does NIST recommend for OTP expiration? NIST SP 800-63B-4 does not prescribe a fixed time limit. It requires OTP lifetimes to be calculated based on clock drift, network delay, and user entry time. The widely cited “10-minute maximum” is a misquote — the standard defines a methodology, not a cap.
How do you handle expired OTPs without frustrating users? Distinguish expired-code errors from wrong-code errors. When a code expires, auto-send a fresh one (within your send rate limits) and tell the user: “This code has expired. We’ve sent a new one.” Do not count expired entries against the user’s attempt limit.
—
Arkesel’s Phone Number Verification delivers OTPs via SMS and voice with built-in expiration, rate limiting, and delivery fallback — so you do not build OTP infrastructure from scratch. Explore the developer documentation to get started.






