Laravel Cache

Use Cache for Short-Lived Tokens Instead of Database Columns

Store temporary verification tokens, OTPs, and one-time codes in Laravel's cache with a defined TTL instead of adding temporary columns to database tables.

When implementing email verification codes, SMS OTPs, or passwordless login tokens, a common instinct is adding temporary columns (such as verification_code and verification_expires_at) to the users table.

For data that is temporary by design, adding columns to permanent database tables creates schema clutter and requires recurring cleanup queries. Laravel's cache provides a cleaner mechanism for short-lived state with automatic expiration.

Storing and Verifying Temporary Tokens

You can store the token with a defined expiration time using Cache::put(), retrieve it upon verification, and consume it immediately with Cache::forget():

use Illuminate\Support\Facades\Cache;

// Temporarily store the token for 10 minutes.
Cache::put(
    'verify:'.$user->id,
    $token,
    now()->addMinutes(10),
);

// Retrieve the temporary token.
$cached = Cache::get('verify:'.$user->id);

if (is_null($cached)) {
    // Expired
} elseif (hash_equals($cached, $request->token)) {
    Cache::forget('verify:'.$user->id);
    // Verified
} else {
    // Invalid token
}

How It Works

  • Self-managing lifecycle: When you pass a DateTime or integer duration to Cache::put(), the cache store automatically discards expired values without requiring scheduled cleanup commands.
  • Timing-safe comparison: Using hash_equals() mitigates timing attacks when comparing sensitive tokens compared to standard equality checks.
  • Immediate invalidation: Calling Cache::forget() immediately consumes the token once verified, preventing replay attempts within the remaining TTL window.

When Cache Fits Best

Using cache is a practical choice for genuinely ephemeral data:

  • Short-lived OTPs or SMS confirmation pins (e.g. 5 to 10 minutes).
  • Email change confirmation tokens.
  • Temporary rate limiting counters and challenge nonces.

When a Database Table Is Better

Cache is not a universal substitute for persistent storage. You should continue using database tables when the data requires:

  • Durable auditing: Preserving an immutable historical record of every issued and redeemed token for compliance.
  • Complex queries: Searching or filtering records across multiple dimensions (such as finding all pending tokens issued by an admin).
  • Guaranteed persistence: Certain cache drivers (like Memcached or Redis under memory pressure) may evict keys before their TTL expires if memory limits are exceeded.
Tags: Laravel Cache Database Architecture
Share on X

// Found an issue or want to contribute a tip? github.com/MrPunyapal/tips