Which cache drivers support the `Cache::touch()` method in Laravel 13?

The core purpose of Cache::touch() in Laravel 13 is to extend the remaining time-to-live (TTL) of a cache entry without reading or rewriting its stored value. It replaces the inefficient "read then write" pattern, making it particularly suitable for scenarios that require "sliding expiration" based on user activity.

Design Motivation and Implementation Principles

Before Laravel 13, extending a cache entry is validity period typically required first retrieving the value with Cache::get(), then storing it back with Cache::put(). This meant the complete serialized data had to travel back and forth over the network, and on high-traffic applications, this overhead was particularly unnecessary when only the expiration time needed adjustment.

The underlying implementation of Cache::touch() directly invokes the driver is native commands, thereby avoiding data transmission:

Redis: Executes a single EXPIRE command.
Memcached: Uses the native TOUCH command.
Database: Executes a single UPDATE statement.

Basic Usage and Return Value Determination

The method accepts two parameters: the cache key and the new TTL (which can be an integer number of seconds, a DateTime instance, or null to indicate permanent validity).

use IlluminateSupportFacadesCache;

// Extend validity by 1 hour (3600 seconds)
Cache::touch( user_session:123 , 3600);

// Use a DateTime instance
Cache::touch( analytics_data , now()->addHours(6));

The return value of this method is a very practical design: when the key exists and the expiration time was successfully extended, it returns true; if the key no longer exists, it returns false. This allows it to serve as an "extend if still alive, otherwise rebuild" atomic operation primitive:

if (! Cache::touch( isession: .$id, 1800)) {
   // Key has expired, need to regenerate and store
   Cache::put( isession: .$id, $this->rebuildSession($id), 1800);
}

Known Issue with Redis Tagged Cache

Although Cache::touch() is implemented across all first-party drivers, in Laravel 13, using it in conjunction with Redis tagged cache has a confirmed bug. The specific manifestation is: touch() successfully extends the key is TTL in Redis, but does not synchronize and update the entry is expiration score in the tag is internal Sorted Set. When the flushStale() cleanup task runs, it incorrectly removes the tag reference based on the old score, causing a subsequent tags()->flush() to fail to delete the key, and the old data continues to be returned.

According to the community is confirmed workaround, when using Redis tags, temporarily fall back to the put() method to keep the tag in sync:

// Avoid using touch() with Redis tags
$value = Cache::tags([ orders ])->get( order:100 );
if ($value !== null) {
   Cache::tags([ orders ])->put( order:100 , $value, 3600);
}

A fix has been proposed for this issue (re-registering the tag entry in RedisTaggedCache is touch()), but before the fix is merged and released, the above avoidance measure is the safest approach.

 

15 Views