A while back, I shared a tip about using a static variable to avoid repeated lookups within a single request. It worked, but I also called out a caveat with Laravel Octane, where static variables persist across requests, which can cause real problems.
At the time, there was a Spatie package that solved this more cleanly, but it felt like overkill to pull in a dependency for something I used in one or two spots.
Not too long after sharing my tip though, Laravel 11 introduced a built-in once() helper that handles this perfectly.
public function getPermissions(): array
{
return once(fn () => $this->roles->flatMap->permissions->pluck('name')->toArray());
}
The first call runs the callback and memoizes the result. Every subsequent call within the same request returns the cached value, no extra query needed.
Compare that to the old static variable approach.
public function getPermissions(): array
{
static $permissions = null;
if ($permissions === null) {
$permissions = $this->roles->flatMap->permissions->pluck('name')->toArray();
}
return $permissions;
}
The once() version is shorter, but the real advantage is that the framework manages it for you.
If you use Octane, it automatically flushes once() values between requests.
A static variable doesn't get that same treatment, which can lead to stale data leaking across requests.
And in your test suite, Laravel flushes once() values between tests as well, so you won't get unexpected state bleed there either.
Here to help,
Joel
P.S. Performance optimizations can be tricky. A second set of eyes helps catch what you might miss. Schedule a code review.