OTP & SMS Security

Storing OTPs: Redis vs SQL Database

Trade-offs between Redis and SQL for OTP request data. Latency, durability, audit, retention, and a recommended hybrid pattern that uses both.

18 May 20267 min read

StartMessaging Team

Engineering

Redis and SQL serve different needs in OTP storage. Most production systems use both: Redis for the active window, SQL for the audit.

Redis Pros

  • Sub-ms latency on read.
  • Native TTL — auto-expire after 10 min.
  • Atomic INCR for attempt counters.

SQL Pros

  • Durable — survives Redis crash.
  • Long-term retention for audit (7+ years).
  • Joinable with user / session tables.

Recommended Hybrid

  • Redis: active OTP request (10-min TTL), attempt counters, rate-limit buckets.
  • SQL: audit row written on send and updated on verify.

Patterns

// On send:
await redis.set(`otp:${requestId}`, JSON.stringify(meta), 'EX', 600);
await db.insert('otp_audit').values({ requestId, status: 'sent', ... });

// On verify:
const meta = await redis.get(`otp:${requestId}`);
// ... verify with provider ...
await redis.del(`otp:${requestId}`);
await db.update('otp_audit').set({ status: 'verified', verifiedAt: now }).where({ requestId });

FAQ

See our schema guide for the SQL side.

Ready to Send OTPs?

Integrate StartMessaging in 5 minutes. No DLT registration required.