An OTP — one-time PIN — is a code valid once, for one action, within a short window. Two-factor authentication (2FA) uses it as a second factor alongside the password.
When it is worth using
Not every action needs a code. Put an OTP where a mistake is expensive:
- signing in from a new device or an unusual location;
- changing the password, email address or phone number;
- confirming a payment or a transfer;
- deleting the account or important data.
If you ask for a code at every step, users learn to type it mechanically — and then it protects nothing.
What a good code looks like
Six digits is the practical standard. Enough that it cannot be guessed, few enough to hold in memory between the notification and the input field.
Short validity. Three to five minutes covers any reasonable network delay. Beyond ten minutes the attack window is needlessly wide.
Cryptographic generation. Use a secure generator, not rand(). A predictable code is not a code.
Single use. Invalidate the code the moment it is used successfully — not when it expires.
The message text matters
Include the application name, the purpose of the code and how long it lasts. Do not include links: an OTP message with a link is exactly the pattern phishing attacks use, and your users need to learn not to click.
H8REV9 is your validation code for YourCompany. Valid for 3 minutes.
That is all. No promotions, no "tap here".
Rate-limit the attempts
A six-digit code has a million combinations. Without limits, a script can try them all. Lock after five wrong attempts and require restarting the flow. Rate-limit resends too — otherwise your form becomes a tool for sending SMS at your expense.
What to do when the code does not arrive
Offer a clear alternative: resend after 60 seconds, a secondary method (email, authenticator app) and a path to support. A user stuck with no way out is a lost user.
On the delivery side, priority-zero routes exist for exactly this reason: a code that arrives in two minutes is no longer a code.