Back to blog Quality and Trust

SMS OTP Suppression Windows: How to Reduce Duplicate Resends Without Blocking Legitimate Users

An SMS OTP suppression window reduces repeated requests without turning a delivery or coverage issue into a lockout. This framework separates validity, resend waiting periods, request state, abuse limits, and delivery evidence.

Operational diagram of states and timers for SMS OTP requests

The Operational Problem: Resends Are Not Just a UX Feature

When a person requests an SMS OTP code several times, the system may generate simultaneous codes, increase messaging costs, create confusion about which code to enter, and expand the attack surface. It can also increase support contacts when users receive delayed messages or when an earlier code stops working without a clear explanation.

However, rigidly suppressing every repeated request can also prevent legitimate authentication. Delays may occur in the network, messaging provider, handset, or the user's connectivity. In addition, some users cannot always rely on mobile coverage and need access to authorised authentication alternatives.

An SMS OTP suppression window is an operational control that decides whether a new request should be accepted, delayed, or prevented from generating another SMS. It does not replace OTP security controls: it should work alongside limited secret validity, one-time acceptance, verification attempt limiting, and risk assessment.

  • Security objective: limit request abuse and verification attempts.
  • Operational objective: prevent duplicate messages and inconsistent states.
  • User experience objective: communicate the wait without revealing whether an account or number exists.
  • Accessibility objective: provide alternative methods when SMS cannot be used.
The Operational Problem: Resends Are Not Just a UX Feature

What a Suppression Window Governs

A suppression window should not answer only the question, “How much time has passed since the last click?” It should govern a complete decision: whether a new request is created, an active request is reused, sending is postponed, a pending attempt is cancelled, or the user is directed to an authorised alternative.

The decision should be deterministic on the server. The interface may display a countdown, but it must not be the authority on when a resend is allowed. The server retains the request state, evaluates limits and risk, issues the code, and decides which secret can be verified.

It is important to explicitly define the treatment of earlier codes. A common policy is to invalidate previous codes when a new one is issued for the same purpose and authentication request. If this policy is adopted, it must be communicated to the user and applied atomically to prevent two codes from remaining valid due to a concurrency condition.

  • Allow: no active request requires suppression and the limits allow sending.
  • Delay: the request is legitimate, but the resend cooldown is still active.
  • Suppress: duplication is detected, an equivalent operation is already in progress, or an applicable restriction has been exceeded.
  • Escalate or change channel: risk, accessibility, or a confirmed technical failure justifies an authorised alternative route.
What a Suppression Window Governs

Separate the Three Essential Timers

Code validity, resend cooldown, and request expiration are distinct timers. Combining them commonly produces two errors: keeping a code acceptable for longer than necessary or denying a legitimate resend because the waiting period is confused with cryptographic validity.

Code validity defines how long the verifier may accept the secret. NIST states that out-of-band authentication must be completed within 10 minutes and that the same secret must be accepted only once during its validity period. An implementation may choose a shorter validity period if its risk analysis and user experience justify it.

Resend cooldown defines how long a person must wait before requesting another SMS. It is a separate operational decision: it should reduce repeated taps and duplicate traffic without being treated as proof that the first SMS will not arrive. Request expiration determines when the authentication transaction is closed and a new flow must be started.

  • Code validity: controls acceptance of the secret and its resistance to replay.
  • Resend cooldown: controls the frequency of new sends.
  • Request expiration: closes the transactional context and prevents indefinite states.
  • Verification attempt limit: controls failed attempts and must not reset when another code is issued.

State Model for an OTP Request

Model the OTP request as an internal transaction with a unique identifier. Messaging provider states should be associated with that transaction, but they must not independently control code validity or the authentication outcome.

A minimum model may include created, accepted, sent, final status reported, verified, expired, and cancelled. The “final status reported” state represents that a terminal update has been received from the messaging system, but it does not claim that the user has seen, read, or used the SMS.

Transitions must be server-controlled and idempotent. For example, a successful verification must close the possibility of reusing the secret, even if a delayed delivery callback arrives afterward. Likewise, an out-of-order external update must not reopen an expired, cancelled, or already verified request.

  • Created: the authentication context exists, but sending has not yet been accepted.
  • Accepted: internal validations passed and the system decided to start sending.
  • Sent: the system recorded issuance to messaging connectivity.
  • Final status reported: an external terminal status was received, and its semantics must be retained without overinterpreting it.
  • Verified: the valid secret was returned and accepted only once.
  • Expired or cancelled: the request can no longer result in successful authentication.

Evidence for Resend Decisions and the Limits of DLRs

The strongest authentication evidence is successful verification of the secret within its validity period. A transport event does not replace the user's explicit response or prove that the code was received, read, or entered on the handset.

To decide on a resend, rank evidence by its function. Internal events indicate whether an active request already exists, whether a code remains valid, whether verification occurred, or whether limits were reached. The send response shows whether the messaging system accepted or rejected the operation according to its interface. DLRs can provide reported delivery-status information, but their interpretation depends on the semantics available across the messaging chain.

A DLR reported as delivered must not be treated as independent confirmation of physical receipt, reading, or legitimate possession of the handset. A pending DLR does not prove failure either. The suppression policy should avoid both immediate resending because no DLR is available and automatic blocking because a delivered DLR exists.

  • Use internal state to retain decision authority.
  • Retain the send response and its correlation identifier.
  • Store the original DLR, its receipt time, and its relationship to the message.
  • Do not turn a DLR into evidence of reading, identity, consent, or authentication success.
  • Validate the OTP on the server even when delivery has been reported.

Practical Rules by Scenario

For the first request, validate and normalise the destination according to the applicable international numbering framework, create the transaction, generate the short-lived secret, and record the event before initiating sending. The result should be associated with request, code, and message identifiers without logging the secret in plain text.

For an early resend, if an active request exists and the cooldown has not elapsed, do not automatically generate another code. Return a generic response indicating the applicable waiting period and keep the option to enter the current code. If a resend is permitted when the cooldown ends, apply the chosen policy for the previous code atomically.

When the code has expired, close the previous request and create a new one only if limits and risk signals allow it. If the platform confirms a technical failure before sending has been accepted, a retry exception may be defined; that exception must be traceable and must not become an unlimited generation mechanism.

When changing channels, do not assume SMS is appropriate in every case. PSTN use for out-of-band authentication has risks that must be assessed. Consider available risk signals, such as device changes, SIM changes, or porting, and direct the user to an authorised alternative authenticator when policy requires it.

  • First request: create context, log, send, and activate timers.
  • Resend during cooldown: retain the active code and display the waiting time.
  • Expired code: close the previous context before issuing a new one.
  • Confirmed technical failure: apply a limited, idempotent, auditable exception.
  • Channel change: preserve the risk context and do not weaken verification controls.

Pending, Rejected, or Delivered DLRs: A Prudent Approach

A pending DLR indicates that no terminal update is yet available for that operation. It is not sufficient reason to immediately issue another SMS. Maintain the cooldown window and allow the user to enter the code while it remains valid.

A reported rejection or failure may justify a controlled retry policy if it is confirmed that sending was not accepted or did not progress according to defined internal criteria. Even then, the retry must be subject to limits and an idempotency key so that network retries do not create multiple messages.

If delivery is reported, retain the non-equivalence rule: the system may record that status for operational analysis, but it must not block every alternative or conclude that the user already has the code. Authentication is completed only when the verifier accepts the valid secret returned by the person.

  • Pending: wait, retain the request, and do not infer failure.
  • Rejected: check the technical meaning of the event before retrying.
  • Delivered: record it as a transport signal, not as reading or authentication.
  • Out of order: retain the event for diagnostics without rolling back internal state.
  • Duplicate: accept the callback idempotently and avoid repeated effects.

Abuse Controls Without Blocking Legitimate Users

Resend suppression should be combined with request limits and verification limits. Short OTPs require limits on failed verification attempts to reduce online guessing. Issuing a new code must not reset that failure counter.

Do not base controls solely on an IP address. OWASP recommends associating failure counters with the account and using IP, device, location, time, and behaviour as complementary signals. For OTP requests, the destination number, account, session, and device can provide different context; none should be treated as proof of identity on its own.

Apply graduated measures rather than a single binary response. NIST considers increasing delays, bot detection, and adaptive evaluation as techniques that can complement rate limiting. Review false positives: travel, shared networks, new devices, limited coverage, and accessibility needs may explain legitimate behaviour.

  • Account limits: protect the associated authentication flow.
  • Number limits: reduce sending pressure to a specific destination.
  • Session and device limits: help detect automated repetition in the same context.
  • IP and other signals: provide context but must not be the sole criterion.
  • Graduated escalation: waiting, an additional challenge, an authorised alternative, or review, depending on risk.
FAQ

Frequently asked questions

What is an SMS OTP suppression window?

It is a server-side rule that decides whether a new SMS OTP code request is allowed, delayed, or suppressed. Its purpose is to reduce duplicate resends and abuse without unnecessarily preventing legitimate authentication.

Should the suppression window be the same as OTP expiration?

No. Expiration defines how long a code can be accepted; the suppression window defines when another SMS can be requested. They are separate controls and should be configured and logged separately.

Does a delivered DLR prove that the user received or read the OTP?

No. A DLR is a delivery-status signal reported by the messaging chain. It does not by itself mean the message was read, the handset was legitimately possessed, or authentication succeeded. The relevant evidence is that the user returns a valid secret within its validity period.

Should the previous code still work after a resend?

The policy must define this explicitly. If a new code invalidates the previous one, apply the invalidation atomically and explain it clearly in the interface. In all cases, each accepted secret must be single-use.

Should the failed-attempt limit reset when another OTP is sent?

No. Generating a new secret must not reset the authentication failure counter. Separating the verification limit from resend controls reduces the risk of online guessing.

What should an OTP implementation log?

Log request, message, and event identifiers; state transitions; suppression decisions; send responses; DLRs with their original semantics; verifications; failures; limits; and exceptions. Avoid logging the OTP secret in plain text.

Sources consulted

  1. NIST SP 800-63B-4: autenticación fuera de banda y PSTNNational Institute of Standards and Technology (NIST)
  2. OWASP Authentication Cheat SheetOWASP Foundation
  3. ITU-T Recommendation E.164: plan internacional de numeración pública de telecomunicacionesInternational Telecommunication Union (ITU)
  4. 3GPP Specifications by Series3rd Generation Partnership Project (3GPP)