You are exactly right! Setting the stale parameter to null (as in [now()->addHour(), null]) means the cache will always return the (possibly stale) cached value, and if it's "too old," the cache will be rebuilt in the background. Your users will never wait for a fresh value—there will be zero "cold cache" hits. Laravel's implementation ensures no request ever has to do all the paging work unless the cache is totally missing. Perfect for your scenario, where staleness isn't a big deal!
Flexible Cache
I have an application that displays statistics collected by another application. It gets the data via API. It also uses some filters, for example the users. So it get the list of all users via an API as well.
There are just a couple of hundreds users, but since the API response are paginated the app needs to go through all the pages and collect the users. This would be called every time the Livewire component to show the stats, and therefore the filters, is mounted.
To speed things up the list of users is cached, and I am currently using the Cache::flexible() method so that I will get the list of users quickly in any case, even though it may be incomplete. I'm ok with this as users don't change that often.
Cache::flexible(
key: 'all-users',
ttl: [now()->addHour(), now()->addHour()->addMinute()],
callback: function () {
/** @var Collection<int, array<string, mixed>> $users */
$users = new Collection;
$this->foreachPage(new Users, function (Response $response) use ($users): void {
$response->collect('data')->each(fn (array $user) => $users->push($user));
});
return $users->map(fn (array $user): string => $user['email'])->all();
},
);
As I understand, with this code if the requests come within one hour the value in the cache is returned. If it comes within one hour and and one minute, the cache is returned and it's also rebuilt in the background. If it comes after one hour and one minute, the cache is rebuilt.
The last part is what I am unhappy with. Since access to the stats page is not that frequent there is a highly chance that the request will come after one hour and one minute from the initial cache creation, and therefore rebuilding the whole cache.
I could increase the stale period, but still there is the chance that we hit the time when the cache is rebuilt. I would like to avoid that.
So my question is, if I set the stale parameter to null, would that mean that no matter when the request come, the cached value will always be returned, but the cache will be rebuild if it's after one hour? I actually looked a the Illuminate\Cache\Repository implementation and I think I am right, but it would be good if someone else could confirm it.
To be clear, the following code will always return the cache, and maybe rebuild it after one hour
Cache::flexible(
key: 'all-users',
ttl: [now()->addHour(), null],
callback: function () {
// ...
},
);
Please or to participate in this conversation.