Files
SealShare/.claude/skills/laravel-best-practices/rules/caching.md
T
Andreas Reinhold / reiniandClaude Opus 4.8 4391ad7fb9 Regenerate Boost guidelines and skills
Byproduct of the Laravel 13 upgrade: composer's post-update-cmd runs
`artisan boost:update`, and Boost went 2.1.3 to 2.4.x with the update.

Refreshes CLAUDE.md and boost.json for the Laravel 13 / Livewire 4 stack,
updates the livewire, pest and tailwindcss skills, replaces the
developing-with-fortify skill with fortify-development, and adds new
laravel-best-practices and octane-development skills.

Generated output, not hand-edited.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 11:17:04 +02:00

2.4 KiB

Caching Best Practices

Use Cache::remember() Instead of Manual Get/Put

Cleaner cache-aside pattern that removes boilerplate. use Cache::lock() for race conditions.

Incorrect:

$val = Cache::get('stats');
if (! $val) {
    $val = $this->computeStats();
    Cache::put('stats', $val, 60);
}

Correct:

$val = Cache::remember('stats', 60, fn () => $this->computeStats());

Use Cache::flexible() for Stale-While-Revalidate

On high-traffic keys, one user always gets a slow response when the cache expires. flexible() serves slightly stale data while refreshing in the background.

Incorrect: Cache::remember('users', 300, fn () => User::all());

Correct: Cache::flexible('users', [300, 600], fn () => User::all()); — fresh for 5 min, stale-but-served up to 10 min, refreshes via deferred function.

Use Cache::memo() to Avoid Redundant Hits Within a Request

If the same cache key is read multiple times per request (e.g., a service called from multiple places), memo() stores the resolved value in memory.

Cache::memo()->get('settings'); — 5 calls = 1 Redis round-trip instead of 5.

Without tags, invalidating a group of entries requires tracking every key. Tags let you flush atomically. Only works with redis, memcached, dynamodb — not file or database.

Cache::tags(['user-1'])->flush();

Use Cache::add() for Atomic Conditional Writes

add() only writes if the key does not exist — atomic, no race condition between checking and writing.

Incorrect: if (! Cache::has('lock')) { Cache::put('lock', true, 10); }

Correct: Cache::add('lock', true, 10);

Use once() for Per-Request Memoization

once() memoizes a function's return value for the lifetime of the object (or request for closures). Unlike Cache::memo(), it doesn't hit the cache store at all — pure in-memory.

public function roles(): Collection
{
    return once(fn () => $this->loadRoles());
}

Multiple calls return the cached result without re-executing. Use once() for expensive computations called multiple times per request. Use Cache::memo() when you also want cross-request caching.

Configure Failover Cache Stores in Production

If Redis goes down, the app falls back to a secondary store automatically.

'failover' => ['driver' => 'failover', 'stores' => ['redis', 'database']],