OTP & SMS Security

Implementing OTP Resend Cooldown

How to implement a polished OTP resend flow with cooldown timer, exponential back-off, server-side enforcement and clear UX. Patterns for web and mobile.

19 May 20266 min read

StartMessaging Team

Engineering

Resend cooldowns prevent users from accidentally (or maliciously) firing repeated OTPs. Combined with server-side enforcement, they cap your wallet exposure.

Why Cooldown Matters

  • Wallet protection — every resend costs.
  • Carrier rate-limit avoidance.
  • User confusion reduction (which OTP is current?).

Progressive Cooldown

  • Resend 1: 30s.
  • Resend 2: 60s.
  • Resend 3: 120s.
  • Past resend 3: lock out, restart flow.

Server-Side Enforcement

async function canResend(phone: string) {
  const k = `resend:${phone}`;
  const count = parseInt(await redis.get(k) ?? '0');
  const since = await redis.ttl(k);
  const required = [30, 60, 120][count] ?? 999;
  return since < (required - 1) ? false : true;
}

UX Patterns

  • Disabled button with countdown text.
  • Auto-focus OTP input after send.
  • Allow one-tap voice fallback after the second resend fails.

FAQ

Combine with idempotency keys to handle network retries cleanly.

Ready to Send OTPs?

Integrate StartMessaging in 5 minutes. No DLT registration required.