Skip to main content
Two-factor authentication (2FA) emails deliver one-time passcodes (OTPs) that users need to complete a login or sensitive action. These emails have the strictest delivery requirements of any email type — they must arrive within seconds, contain a short-lived code, and resist interception. A failed or delayed 2FA email locks the user out entirely. This guide covers OTP generation, email design, delivery optimization, and security hardening.

Delivery Speed Requirements

2FA emails are the most time-sensitive email type. Users are waiting on a login screen and will abandon the flow if the code doesn’t arrive quickly.

Optimizing for Speed

  • Send immediately — never queue 2FA emails behind other sends. Use the highest priority in your sending pipeline.
  • Keep the email tiny — minimal HTML, no images, no tracking pixels. Every byte adds processing time at each hop in the delivery pipeline.
  • Use a warmed, reputable domain — established sending domains are processed faster by receiving servers. See IP and Domain Warm-Up.
  • Monitor delivery latency — alert if the time between your API call and the email.delivered webhook event exceeds 10 seconds.
Do not include open or click tracking in 2FA emails. Tracking pixels add processing overhead, increase email size, and provide no useful data — you already know the user received the code if they successfully log in.

OTP Generation and Security

Generate Secure Codes

Use a cryptographically secure random number generator. The code should be numeric (for easy entry on mobile) and 6–8 digits:
Don’t use Math.random() for OTP generation. It’s not cryptographically secure and produces predictable sequences that an attacker could guess.

Set Short Expiry Times

OTP codes should expire quickly. The user is actively waiting to enter the code:

Invalidation Rules

  • Single use — invalidate the code immediately after successful verification
  • New code invalidates old — when a user requests a new code, invalidate all previous codes for that user
  • Maximum attempts — lock the account temporarily after 5 failed verification attempts

Email Content

2FA emails should be the simplest emails you send. The user needs the code and nothing else.

Template Structure

Design Principles

  • Large, monospaced code — make the code easy to read and distinguish similar characters (0 vs O, 1 vs l)
  • Letter spacing — add space between digits so users can read them in groups
  • No clickable links for the code — the user should type the code manually, not click a link (clicking a magic link is a different authentication pattern)
  • Minimal content — no marketing, no navigation, no images beyond a simple logo
  • Clear expiry notice — tell the user how long the code is valid
  • Security warning — if they didn’t request the code, tell them what to do
Use font-family: 'Courier New', monospace for the OTP code. Monospaced fonts prevent confusion between similar characters like 0 and O, or 1 and l.

Plain-Text Version


Sending with Lettr

Put the code in the email subject line (e.g., “847203 is your verification code”). Many users can read and enter the code directly from their phone’s notification banner without opening the email, reducing friction.

Rate Limiting

2FA emails are a common target for abuse — attackers may trigger OTP sends to flood a user’s inbox or exhaust your sending quota.

Implement Rate Limits


Fallback Strategies

Email delivery is not guaranteed to be fast enough for 2FA. Plan for failures.

Resend Option

Provide a “Resend code” button on the verification screen, but enforce a cooldown:
  • 30-second cooldown between resend requests
  • Maximum 3 resends per verification session
  • Generate a new code on each resend (invalidating the previous one)

Alternative Channels

Consider offering fallback options when email delivery is slow:
  • Authenticator app (TOTP) — no delivery delay, works offline
  • SMS — faster delivery than email in most cases, but has its own reliability issues
  • Backup codes — pre-generated codes the user stored during setup
Email-based 2FA is less secure than authenticator apps (TOTP) because email can be intercepted or the inbox compromised. If your application handles sensitive data, offer TOTP as the primary option and email as a fallback.

Common Mistakes

A 4-digit code has only 10,000 possible values — an attacker with no rate limiting can brute-force it quickly. Use 6 digits minimum, and enforce strict attempt limits.
A non-expiring OTP gives attackers unlimited time to intercept and use it. Set a 5-minute expiry as the default.
Tracking pixels add latency and size to the email. For 2FA, delivery speed matters more than open tracking. Disable tracking for OTP emails.
A domain without established reputation may experience delivery delays — exactly when you need speed most. Use a warmed sending domain.
Without rate limits, an attacker can trigger thousands of OTP emails, flooding the user’s inbox and burning through your sending quota.
If your database is compromised, raw OTP codes give attackers immediate access. Hash the code before storing it, just like passwords.
An OTP generated for login should not be valid for a password change. Bind each code to a specific action and validate the action context during verification.

Password Reset Emails

Secure password reset flows and token management

Security Best Practices

API key security, webhook verification, and account protection

Deliverability Best Practices

Maximize inbox placement and delivery speed

Sending Reputation

Build and protect your sender reputation