Cache::flexible()
Serve stale cache immediately while refreshing in the background — the stale-while-revalidate pattern built into Laravel.
Overview
Cache::flexible() implements the "stale-while-revalidate" caching strategy. It defines two TTLs: a "fresh" period and a "stale" period. During the fresh period, cached data is returned as-is. During the stale period, the cached data is still returned immediately, but a background process refreshes it for the next request.
Usage
use Illuminate\Support\Facades\Cache;
$users = Cache::flexible('active-users', [300, 600], function () {
return User::where('is_active', true)->get();
});
The two-element array defines:
- 300 seconds (5 min): the "fresh" window — cached value is returned, no refresh triggered
- 600 seconds (10 min): the "stale" window — cached value is returned immediately, but a background refresh is dispatched
After both windows expire, the next request blocks and recomputes the value.
Comparison with Cache::remember()
// Standard remember — blocks when cache expires
Cache::remember('users', 300, fn () => User::all());
// Flexible — never blocks during the stale window
Cache::flexible('users', [300, 600], fn () => User::all());
With remember(), when the 5-minute TTL expires, the next user waits for the query. With flexible(), that user still gets the stale data instantly while the cache refreshes behind the scenes.
Real-World Example
Dashboard stats that should feel instant but stay reasonably fresh:
$stats = Cache::flexible('dashboard-stats', [60, 300], function () {
return [
'total_users' => User::count(),
'revenue_today' => Order::whereDate('created_at', today())->sum('total'),
'active_sessions' => Session::where('last_active', '>', now()->subMinutes(5))->count(),
];
});
When to Use
- Dashboard widgets and analytics that must feel instant
- API responses where staleness is acceptable for a few minutes
- Any expensive query where you'd rather show slightly outdated data than make the user wait
- High-traffic pages where cache stampedes are a concern