Laravel Tutorials

Memoize Tagged Cache Reads in Laravel

Published
Memoize Tagged Cache Reads in Laravel image

Laravel's memoized cache, Cache::memo(), reads a key from your cache store once and serves it from memory for the rest of the request or job. Starting in Laravel 13.33, it also works with cache tags, so you can memoize tagged values with Cache::memo()->tags().

This helps when one request reads the same tagged value many times. A permission lookup might run for every can() call and every @can directive in a view, and without memoization each one goes back to the cache store.

Memoizing a Tagged Lookup

Call tags() on the memoized cache and use it like any other tagged cache:

use Illuminate\Support\Facades\Cache;
 
public function getPermissions(User $user): Collection
{
return Cache::memo()
->tags(['permissions', "user:{$user->id}"])
->remember(
"permissions:{$user->id}",
now()->addHour(),
fn () => $this->loadPermissionsFromDatabase($user)
);
}

The first call in a request reads from the cache store, or runs the closure on a cache miss. Later calls with the same tags and key return the value from memory.

Before the memoized cache supported tags, the workaround was to wrap the tagged cache in an array store yourself:

return Cache::store('array')->tags('permission_cache')->rememberForever($cacheKey,
fn () => Cache::tags($this->cacheTags($user))->remember(
$cacheKey,
config('auth.permissions.default_cache_time'),
fn () => $this->loadPermissionsFromDatabase($user)
)
);

Writes and Flushes

Methods that change a value write to the tagged cache and drop the memoized copy of that key, so the next read goes back to the store:

$cache = Cache::memo()->tags(['permissions']);
 
$cache->get('permissions:1'); // Reads from the cache store
$cache->get('permissions:1'); // Reads from memory
 
$cache->put('permissions:1', $updated); // Writes to the store, forgets the memoized value
$cache->get('permissions:1'); // Reads from the cache store again

This covers put(), putMany(), add(), increment(), decrement(), forever(), touch(), and forget(). Calling flush() on a memoized tagged cache flushes the tags in the store and clears the memoized tagged values.

When to Use It

The memoized cache holds what the current request has already read. If a queue worker or another request changes the value, this request does not see the change.

I would use it for values that do not change during a request, like permissions or settings. Keep counters and anything another process updates mid-request on the regular cache.

The memoized values reset at the start of each request or job, so long-running workers do not keep stale data between jobs.

Further Reading

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Sponsored

serpapi logo
SerpApi

The Web Search API for Your LLM and AI Applications

Visit SerpApi

The latest

View all →
Running Laravel's Scheduler on Multiple Servers image

Running Laravel's Scheduler on Multiple Servers

Read article
Laravel Fake Assertions Now Accept Property Arrays image

Laravel Fake Assertions Now Accept Property Arrays

Read article
Route::query() and Model defaults() in Laravel 13.35 image

Route::query() and Model defaults() in Laravel 13.35

Read article
Laravel AI SDK 1.1 Adds Agent Skills and Cohere Chat image

Laravel AI SDK 1.1 Adds Agent Skills and Cohere Chat

Read article
VMPal: Give Your AI Agent a Whole Computer image

VMPal: Give Your AI Agent a Whole Computer

Read article
Synapse: A Dev Dashboard for Laravel AI SDK Agents image

Synapse: A Dev Dashboard for Laravel AI SDK Agents

Read article