View Full Flow here → https://excalidraw.com/#json=VR9NX3z1idksebwzMdtIv,J6I-mKx_H7XgHdXO0SQqbA
🧩 Step 1: What Are We Actually Building?
We’re designing a system where:
- A user enters their email (or phone number).
- They receive an OTP (One Time Password).
- They enter that OTP to verify their identity and log in.
No passwords. No user accounts yet. Just identity verification via a one-time secret.
Now — if you’re a beginner, your brain immediately asks:
“Can’t I just generate an OTP and store it in the database?”
That’s a fair thought.
Let’s start there and evolve step by step like an architect would.
🧠 Step 2: Why We Don’t Store OTP in the Database
When you first imagine it, you might think:
“I’ll just create a table like otps with columns: email, otp, expiry.”

But here’s what goes wrong in production:
- Database I/O is expensive
- Databases like Postgres or MySQL are designed for persistent storage, not short-lived data.
- OTPs live for 30–60 seconds, not months.
- Writing + deleting OTPs constantly creates unnecessary load and storage bloat.
- Concurrency problems
- OTPs are generated and verified rapidly by thousands of users at once.
- You don’t want your relational DB handling that hot traffic.
- Security implications
- Storing OTPs in plain text in a DB means if your DB is leaked, users’ OTPs are exposed.
- Even if hashed, rotating millions of short-lived records is wasteful.