Cache Operations

Storing, Retrieving, and Removing Cached Items

Besides put($key, $value, $seconds), add() (only if absent), forever(), get(), has(), increment(), pull() and forget(), the workhorse is remember(), which returns the cached value or runs the closure and stores its result:

remember() around a slow shop query, timed in tinkerPHP
Cache::forget('shop:bestsellers');
foreach (['miss', 'hit', 'hit'] as $label) {
    $t = hrtime(true);
    $top = Cache::remember('shop:bestsellers', 600, fn () => DB::table('order_items as oi')
        ->join('orders as o', 'o.id', '=', 'oi.order_id')->where('o.status', 'shipped')
        ->groupBy('product_id')->orderByDesc('revenue')->limit(3)
        ->selectRaw('product_id, SUM(quantity * unit_price) AS revenue')->get()->all());
    printf("%-4s %8.2f ms  %s\n", $label, (hrtime(true) - $t) / 1e6, get_class($top[0]));
}
Output
miss   252.21 ms  stdClass
hit      0.57 ms  __PHP_Incomplete_Class
hit      0.33 ms  __PHP_Incomplete_Class

Redis 2,763 answered in half a millisecond, but with broken objects: Laravel 13 2,157 's 'serializable_classes' => false rebuilds no class, not even stdClass. Cache arrays (->map(fn ($row) => (array) $row), as ShopReports::bestsellers() does below) or list the classes you trust.

Cache::flexible($key, [5, 30], $fn) is stale-while-revalidate: fresh for 5 s, then until 30 s it serves the stale value and refreshes it after the response. A /top route returns Cache::flexible('shop:top', [5, 30], ShopReports::bestsellers(...)) and its build time as X-Ms:

Cold, fresh, stale and refreshed requestsPHP
for pause in 0 1 5 3; do sleep $pause
  curl -s -o /dev/null -D - -w 'client %{time_total}s\n' $B/top | grep -E 'X-Ms|client' \
    | tr -d '\r' | paste -sd' '
done
Output
X-Ms: 772.2 client 0.813773s
X-Ms: 1.4 client 0.035293s
X-Ms: 2.4 client 0.814313s
X-Ms: 1.6 client 0.022391s

The stale third response was ready in 2.4 ms and the refresh ran afterwards, so the fourth was fresh. curl 3,008 still waited, because php -S holds the connection until deferred work ends; under PHP-FPM, Response::send() calls fastcgi_finish_request() first.