Jumat, 26 December 2025

Belajar Cache Flexible di Laravel

Cache pada dasarnya dipakai untuk menghindari kerja mahal yang berulang, misalnya query agregasi berat atau pemanggilan API eksternal, dengan menyimpan hasilnya agar request berikutnya lebih cepat.

Laravel

Masalah yang diselesaikan

Saat kamu memakai Cache::remember, ada momen ketika cache expired dan request yang datang pada saat itu harus menghitung ulang nilai cache. Laravel sendiri menyorot bahwa sebagian user bisa mengalami respons lambat ketika nilai cache expired. Cache::flexible hadir untuk mengurangi latency spike ini dengan pola stale while revalidate: tetap sajikan nilai cache yang sudah tidak fresh (stale) untuk sementara, lalu refresh cache setelah response terkirim.

Cara kerja Cache::flexible

Bentuk umumnya:

Cache::flexible($key, [$freshSeconds, $staleSeconds], $callback)

Laravel menjelaskan bahwa method ini menerima array dua angka:

  • $freshSeconds: durasi cache dianggap fresh
  • $staleSeconds: batas akhir cache masih boleh disajikan sebagai stale sebelum wajib dihitung ulang langsung

Yang terjadi saat runtime

Kalau request datang saat masih fresh, nilai cache langsung dipakai.

Kalau request datang saat sudah stale, nilai lama tetap dipakai supaya respons cepat, lalu Laravel menjadwalkan refresh setelah response terkirim lewat deferred function.

Kalau request datang setelah melewati batas stale, cache dianggap expired dan Laravel menghitung ulang saat itu juga.

Memahami parameter secara praktis

Bagian ini tujuannya biar kamu tidak sekadar “ikut contoh”, tapi benar benar paham apa yang kamu atur di Cache::flexible. Tiga hal yang perlu kamu kuasai adalah key, window waktunya, dan callback. Kalau tiga ini tepat, caching kamu akan stabil, mudah di-maintain, dan tidak bikin kejutan di produksi.

Key

$key adalah identitas unik item cache. Anggap ini seperti nama file untuk satu nilai cache. Kalau key terlalu generik, kamu rawan tabrakan antar fitur atau antar entity. Praktik yang aman adalah bikin key yang konsisten dengan konteks fitur, dan kalau terkait entity tertentu, sertakan identifiernya supaya cache tidak tercampur.

Fresh dan Stale

Dua angka ini bukan sekadar TTL. freshSeconds adalah durasi kamu menganggap data “cukup baru”. Setelah melewati fresh, masuk ke buffer window sampai staleSeconds: pada rentang ini Laravel masih boleh menyajikan data stale agar respons tetap cepat, lalu melakukan refresh setelah response lewat deferred function. Kalau sudah melewati staleSeconds, cache dianggap expired dan harus dihitung ulang pada request itu.

Callback

Callback adalah “cara menghitung” nilai cache. Karena refresh pada buffer window dijalankan setelah response, callback idealnya aman dipanggil ulang dan tidak menimbulkan side effect yang sensitif. Deferred functions di Laravel dijalankan setelah response dan default-nya hanya berjalan jika request berakhir sukses.

Contoh kasus nyata

Contoh sederhana: dashboard menampilkan daftar user terbaru. Data boleh tertinggal sebentar, tapi kamu ingin request tetap cepat.

use App\Models\User;
use Illuminate\Support\Facades\Cache;

$users = Cache::flexible('dashboard:latest_users', [15, 120], function () {
    return User::query()->latest()->limit(25)->get();
});

Artinya: selama 15 detik, cache dianggap fresh. Setelah itu sampai 120 detik, user tetap dapat data cepat (stale kalau perlu), dan Laravel refresh setelah response. Lewat 120 detik, request berikutnya akan hitung ulang langsung.

Kapan sangat disarankan memakai Cache::flexible

Pakai Cache::flexible ketika datanya mahal dihitung ulang dan endpoint-nya read-heavy, tapi data boleh sedikit stale. Ini tipikal untuk metrik dashboard, agregasi analytics, ringkasan performa, dan hasil query berat yang sifatnya informasional. Laravel memposisikan ini sebagai solusi untuk menghindari sebagian user mengalami respons lambat saat cache expired.

Jangan pakai Cache::flexible ketika stale walau sebentar itu berisiko, seperti authorization, saldo, stok ketat, atau keputusan yang berdampak finansial langsung.

Kalau traffic rendah dan kamu tidak peduli spike sesekali saat expired, Cache::remember biasanya cukup.

Mengurangi refresh paralel dengan atomic lock

Kalau callback kamu berat dan traffic tinggi, tambahkan atomic lock supaya refresh tidak jalan paralel. Laravel menjelaskan atomic locks, driver yang mendukung, serta pola closure yang auto release.

use App\Models\User;
use Illuminate\Support\Facades\Cache;

$users = Cache::flexible('dashboard:latest_users', [15, 120], function () {
    return Cache::lock('lock:dashboard:latest_users', 10)->get(function () {
        return User::query()->latest()->limit(25)->get();
    });
});

Kesimpulan

Cache::flexible cocok untuk mengunci latensi agar stabil pada endpoint read-heavy. Kamu mendefinisikan dua fase dengan [freshSeconds, staleSeconds]. Pada fase stale, Laravel tetap mengembalikan nilai lama lalu melakukan refresh setelah response lewat deferred function, sehingga kamu mengurangi spike yang biasanya muncul saat cache expired.