Tags let you flush a group of entries, such as one category's, without knowing the keys; read an item with the tags it was written with. Cache::memo() adds a per-request memory layer, and Cache::touch(), new in Laravel 13 2,157 , extends a TTL without rewriting the value:
Cache::tags(['products', 'category:2'])->put('product:1', 'Modern PHP in Practice', 600);
Cache::tags(['products', 'category:3'])->put('product:2', 'SQL Queries That Scale', 600);
Cache::tags('category:2')->flush();
var_dump(Cache::tags(['products', 'category:2'])->get('product:1'));
var_dump(Cache::tags(['products', 'category:3'])->get('product:2'));
Event::listen(Illuminate\Cache\Events\CacheHit::class, fn ($e) => print("hit {$e->key}\n"));
Cache::put('shop:currency', 'EUR', 600);
foreach ([1, 2, 3] as $i) { $c = Cache::memo()->get('shop:currency'); echo "memo $i: $c\n"; }
Cache::put('shop:banner', 'Autumn sale', 60);
var_dump(Cache::touch('shop:banner', 3600), Cache::touch('shop:nope', 3600));Output
NULL string(22) "SQL Queries That Scale" hit shop:currency memo 1: EUR memo 2: EUR memo 3: EUR bool(true) bool(false)
Flushing category:2 removed product:1 only. Redis 2,763 keeps each tag's members in a sorted set, and tag:products:entries still listed both after the flush, so schedule php artisan cache:prune-stale-tags. Only the first memoized read reached Redis. touch() failed for the missing key, and redis-cli TTL then showed 3600 seconds for shop:banner.