Laravel Cache: Cara Menggunakan Cache untuk Meningkatkan Performa Aplikasi

Apa Itu Laravel Cache?

Laravel Cache adalah mekanisme untuk menyimpan data yang sering digunakan agar aplikasi tidak perlu mengambil atau menghitung data tersebut berulang kali.

Contoh sederhana, sebuah halaman Laravel mengambil daftar kategori dari database:

$categories = Category::orderBy('name')->get();

Setiap kali halaman dibuka, query tersebut akan dijalankan kembali.

Jika data kategori jarang berubah, sebenarnya tidak perlu mengambilnya dari database setiap request.

Kita dapat menyimpan hasil query ke cache:

$categories = Cache::remember(
    'categories',
    3600,
    fn () => Category::orderBy('name')->get()
);

Selama cache masih tersedia, Laravel dapat menggunakan data yang sudah disimpan tanpa menjalankan query database kembali.

Hasilnya, beban database dapat berkurang dan response aplikasi berpotensi menjadi lebih cepat.

Mengapa Cache Penting untuk Aplikasi Laravel?

Semakin besar aplikasi, semakin banyak proses yang dilakukan setiap request.

Misalnya sebuah halaman membutuhkan:

  • Data kategori
  • Data konfigurasi website
  • Daftar produk
  • Statistik dashboard
  • Data dari API eksternal
  • Hasil query database yang kompleks

Jika semua data tersebut selalu diambil ulang, database dan server harus bekerja lebih banyak.

Dengan cache, data yang relatif stabil dapat digunakan kembali.

Secara sederhana:

Tanpa Cache

Request
   ↓
Laravel
   ↓
Database
   ↓
Laravel
   ↓
Response

Dengan cache:

Request
   ↓
Laravel
   ↓
Cache
   ↓
Response

Jika data tersedia di cache, aplikasi tidak perlu selalu mengakses database.

Bagaimana Laravel Cache Bekerja?

Konsep cache cukup sederhana.

Ketika aplikasi membutuhkan data:

  1. Laravel memeriksa apakah data tersedia di cache.
  2. Jika tersedia, Laravel menggunakan data tersebut.
  3. Jika tidak tersedia, Laravel mengambil atau menghitung data.
  4. Hasilnya disimpan ke cache.
  5. Request berikutnya dapat menggunakan data dari cache.

Pola ini sering disebut cache-aside.

Contoh:

$value = Cache::get('site_name');

if ($value === null) {
    $value = 'Website Saya';

    Cache::put('site_name', $value, 3600);
}

Namun Laravel menyediakan helper yang lebih praktis untuk pola tersebut, yaitu remember().

Konfigurasi Cache Laravel

Laravel menyediakan sistem cache melalui konfigurasi:

config/cache.php

Driver cache yang tersedia bergantung pada versi Laravel dan konfigurasi aplikasi.

Beberapa backend yang umum digunakan antara lain:

  • File
  • Database
  • Redis
  • Memcached
  • Array

Untuk melihat konfigurasi environment, periksa .env aplikasi.

Pada instalasi Laravel modern, konfigurasi cache dapat menggunakan:

CACHE_STORE=database

atau menggunakan Redis:

CACHE_STORE=redis

Nama environment variable dapat berbeda tergantung versi Laravel yang digunakan. Karena itu, sebaiknya periksa config/cache.php pada project sebelum mengubah konfigurasi.

Menggunakan Cache dengan Cache::put()

Cara dasar untuk menyimpan data ke cache adalah menggunakan Cache::put().

use Illuminate\Support\Facades\Cache;

Cache::put('site_name', 'Website Saya', 3600);

Parameter ketiga menentukan berapa lama data disimpan.

Pada contoh tersebut:

3600 detik = 1 jam

Setelah satu jam, cache tersebut dapat dianggap expired.

Mengambil Data dengan Cache::get()

Untuk mengambil data dari cache:

$value = Cache::get('site_name');

Jika key tidak ditemukan, hasilnya dapat berupa null.

Kita juga dapat memberikan default value:

$value = Cache::get('site_name', 'Website Saya');

Jika site_name tidak tersedia, Laravel akan mengembalikan:

Website Saya

Menggunakan Cache::remember()

Dalam aplikasi Laravel, Cache::remember() adalah salah satu method yang sangat berguna.

Contoh:

$products = Cache::remember(
    'products',
    3600,
    fn () => Product::latest()->get()
);

Cara kerjanya:

Apakah "products" ada di cache?
          │
       ┌──┴──┐
      Ya    Tidak
      │        │
      ↓        ↓
Ambil cache  Query DB
               │
               ↓
          Simpan cache
               │
               ↓
             Return

Dengan pola tersebut, kita tidak perlu menulis pengecekan cache secara manual.

Contoh Cache Query Database

Misalnya kita memiliki query:

$posts = Post::where('published', true)
    ->latest()
    ->take(10)
    ->get();

Jika query tersebut digunakan berulang kali dan datanya tidak berubah setiap saat, kita dapat menggunakan:

$posts = Cache::remember(
    'latest_published_posts',
    600,
    fn () => Post::where('published', true)
        ->latest()
        ->take(10)
        ->get()
);

Cache tersebut memiliki TTL 600 detik atau 10 menit.

Request pertama akan menjalankan query database.

Request berikutnya selama cache masih tersedia dapat menggunakan hasil yang sudah disimpan.

Cache dengan Key yang Dinamis

Hati-hati menggunakan cache key yang sama untuk data yang berbeda.

Misalnya kita memiliki halaman produk:

/products/1
/products/2
/products/3

Jangan menggunakan:

Cache::remember(
    'product',
    3600,
    fn () => Product::find($id)
);

Karena semua produk menggunakan key yang sama.

Gunakan key yang mengandung ID:

$product = Cache::remember(
    "product:{$id}",
    3600,
    fn () => Product::findOrFail($id)
);

Hasilnya menjadi:

product:1
product:2
product:3

Dengan demikian setiap produk memiliki cache sendiri.

Menghapus Cache dengan Cache::forget()

Cache yang sudah tidak relevan perlu dihapus.

Gunakan:

Cache::forget('products');

Contohnya ketika produk diperbarui:

$product->update($data);

Cache::forget('products');

Dengan begitu request berikutnya tidak menggunakan data lama dari cache.

Menghapus Semua Cache

Laravel menyediakan command untuk menghapus cache aplikasi.

Salah satu command yang umum digunakan:

php artisan cache:clear

Command tersebut menghapus item cache dari cache store yang digunakan aplikasi.

Namun, jangan menjadikan cache:clear sebagai solusi rutin untuk masalah cache.

Dalam aplikasi production, lebih baik mengelola invalidasi cache berdasarkan data yang berubah.

Cache TTL

TTL adalah singkatan dari Time To Live.

TTL menentukan berapa lama sebuah item cache dianggap valid.

Contoh:

Cache::put('settings', $settings, 3600);

Artinya data tersebut disimpan selama sekitar satu jam.

Beberapa contoh TTL:

60 detik     = 1 menit
300 detik    = 5 menit
1800 detik   = 30 menit
3600 detik   = 1 jam
86400 detik  = 1 hari

Pemilihan TTL tergantung pada karakteristik data.

Data yang jarang berubah dapat memiliki TTL lebih panjang.

Data yang sering berubah sebaiknya menggunakan TTL lebih pendek atau menggunakan invalidasi cache ketika data berubah.

Cache forever()

Laravel juga memiliki:

Cache::forever('site_settings', $settings);

Dengan cara ini data disimpan tanpa expiration berdasarkan TTL.

Namun, forever() bukan berarti data tersebut tidak pernah hilang.

Perilaku penyimpanan tetap bergantung pada cache driver yang digunakan dan kondisi infrastrukturnya.

Untuk data yang perlu selalu tersedia, tetap pertimbangkan strategi invalidasi dan fallback.

Mengecek Apakah Cache Tersedia

Gunakan:

if (Cache::has('site_settings')) {
    // Cache tersedia
}

Contoh:

if (Cache::has('site_settings')) {
    $settings = Cache::get('site_settings');
}

Namun, jika tujuan kita adalah mengambil data dan membuatnya jika belum tersedia, biasanya remember() lebih ringkas:

$settings = Cache::remember(
    'site_settings',
    3600,
    fn () => Setting::all()
);

Cache dengan rememberForever()

Jika data jarang berubah, kita dapat menggunakan:

$settings = Cache::rememberForever(
    'site_settings',
    fn () => Setting::all()
);

Tetapi data tersebut tetap perlu dihapus atau diperbarui ketika sumber datanya berubah.

Misalnya:

Cache::forget('site_settings');

Strategi ini disebut cache invalidation.

Apa Itu Cache Invalidation?

Cache invalidation adalah proses memastikan cache tidak lagi digunakan ketika data sumber sudah berubah.

Misalnya database memiliki:

Product A
Harga: Rp100.000

Kemudian harga diubah menjadi:

Rp120.000

Tetapi cache masih menyimpan:

Rp100.000

Aplikasi dapat menampilkan data yang sudah tidak sesuai.

Karena itu, ketika data berubah, cache yang berkaitan harus diperbarui atau dihapus.

Contoh:

$product->update([
    'price' => 120000
]);

Cache::forget("product:{$product->id}");

Cache dan Database Tidak Harus Selalu Sama

Penting untuk memahami bahwa cache hanyalah salinan data.

Database tetap menjadi sumber data utama.

Contohnya:

Database
   │
   ├── Data asli
   │
   ↓
Cache
   │
   └── Salinan untuk akses cepat

Jika cache hilang, aplikasi seharusnya dapat mengambil kembali data dari sumber utama.

Karena itu, jangan menganggap cache sebagai tempat penyimpanan data permanen kecuali memang menggunakan mekanisme khusus yang dirancang untuk kebutuhan tersebut.

Menggunakan Redis sebagai Cache Laravel

Untuk aplikasi dengan traffic lebih tinggi, Redis sering digunakan sebagai cache backend.

Pada environment Laravel, konfigurasi cache dapat diarahkan ke Redis, misalnya:

CACHE_STORE=redis

Konfigurasi detail Redis bergantung pada versi Laravel dan setup project.

Setelah Redis dikonfigurasi, kode aplikasi tetap dapat menggunakan API Cache yang sama:

$products = Cache::remember(
    'products',
    600,
    fn () => Product::latest()->get()
);

Artinya kode aplikasi tidak perlu berubah hanya karena backend cache berpindah dari satu driver ke driver lainnya.

Kenapa Redis Cocok untuk Cache?

Redis menyimpan data di memory sehingga akses terhadap data cache umumnya sangat cepat.

Redis juga banyak digunakan bersama Laravel untuk kebutuhan lain seperti:

  • Cache
  • Queue
  • Laravel Horizon
  • Session

Jika kamu menggunakan Laravel Queue dengan Redis, memahami cache Redis akan menjadi semakin berguna karena Redis dapat menjadi bagian penting dari arsitektur aplikasi Laravel.

Namun, penggunaan Redis tidak otomatis membuat semua query menjadi cepat. Query database yang buruk, index yang tidak tepat, atau desain aplikasi yang tidak efisien tetap perlu diperbaiki.

Cache di Controller

Cache dapat digunakan langsung di controller.

Contoh:

use Illuminate\Support\Facades\Cache;

class ProductController extends Controller
{
    public function index()
    {
        $products = Cache::remember(
            'products:latest',
            600,
            fn () => Product::latest()->paginate(20)
        );

        return view('products.index', compact('products'));
    }
}

Untuk aplikasi sederhana, pendekatan ini cukup mudah dipahami.

Namun, pada aplikasi yang lebih kompleks, logic caching dapat dipindahkan ke service atau repository agar controller tidak terlalu penuh.

Cache di Service Class

Misalnya kita memiliki:

class ProductService
{
    public function latest()
    {
        return Cache::remember(
            'products:latest',
            600,
            fn () => Product::latest()->get()
        );
    }
}

Controller kemudian menjadi lebih sederhana:

public function index(ProductService $productService)
{
    $products = $productService->latest();

    return view('products.index', compact('products'));
}

Pendekatan ini dapat membantu memisahkan business logic dari HTTP layer.

Cache untuk Data dari API Eksternal

Cache tidak hanya berguna untuk database.

Misalnya aplikasi mengambil data dari API eksternal:

$response = Http::get('https://example.com/api/weather');

Jika data tidak perlu diperbarui setiap detik, kita dapat menyimpannya:

$data = Cache::remember(
    'weather:city',
    300,
    fn () => Http::get('https://example.com/api/weather')->json()
);

Dengan TTL lima menit, aplikasi tidak perlu memanggil API eksternal pada setiap request.

Manfaatnya:

  • Mengurangi request ke API
  • Response lebih cepat
  • Mengurangi risiko terkena rate limit
  • Tetap dapat menggunakan data yang relatif baru

Cache untuk Configuration atau Settings

Data konfigurasi aplikasi yang jarang berubah juga bisa di-cache.

Misalnya:

$settings = Cache::remember(
    'site_settings',
    3600,
    fn () => Setting::pluck('value', 'key')
);

Kemudian ketika admin mengubah settings:

Cache::forget('site_settings');

Request berikutnya akan mengambil data terbaru dari database dan menyimpannya kembali ke cache.

Cache Tags

Beberapa cache backend mendukung konsep cache tags.

Contohnya:

Cache::tags(['products'])->put(
    'product:1',
    $product,
    3600
);

Kemudian cache berdasarkan tag dapat dihapus:

Cache::tags(['products'])->flush();

Namun, dukungan cache tags bergantung pada cache driver yang digunakan. Karena itu, jangan mengasumsikan semua cache backend mendukung fitur ini.

Untuk kebutuhan yang sederhana, cache key biasa sering kali sudah cukup.

Kesalahan yang Sering Terjadi Saat Menggunakan Cache

1. Cache Key Tidak Konsisten

Misalnya saat menyimpan:

Cache::put('products', $products, 3600);

tetapi saat menghapus:

Cache::forget('product');

Key berbeda sehingga cache yang benar tidak terhapus.

Gunakan konvensi key yang konsisten.

2. TTL Terlalu Panjang

TTL satu hari mungkin cocok untuk data tertentu.

Tetapi untuk data yang sering berubah, TTL terlalu panjang dapat membuat user melihat informasi lama.

3. Tidak Melakukan Invalidasi

Jika data berubah tetapi cache tidak dihapus atau diperbarui, aplikasi dapat menampilkan stale data.

4. Semua Data Dimasukkan ke Cache

Tidak semua query perlu di-cache.

Caching sebaiknya dipertimbangkan untuk data yang:

  • Sering dibaca
  • Relatif jarang berubah
  • Mahal untuk dihitung atau diambil
  • Digunakan berulang kali

Query sederhana dengan execution time sangat kecil mungkin tidak memberikan manfaat besar ketika di-cache.

5. Cache Terlalu Besar

Caching data dalam jumlah sangat besar dapat meningkatkan penggunaan memory.

Terutama ketika menggunakan Redis atau cache backend berbasis memory.

Pertimbangkan ukuran data, TTL, dan frekuensi akses.

Cache vs Database

Cache dan database memiliki tujuan berbeda.

AspekCacheDatabase
TujuanMempercepat akses dataPenyimpanan data utama
KecepatanUmumnya sangat cepatBergantung query dan storage
DataBiasanya salinanData utama
TTLUmumnya adaTidak berbasis TTL
Kehilangan dataHarus bisa ditangani aplikasiHarus lebih persisten
ContohRedis, File, MemcachedMySQL, PostgreSQL

Jangan mengganti database dengan cache.

Gunakan cache sebagai lapisan tambahan untuk meningkatkan performa.

Strategi Cache yang Sederhana untuk Laravel

Untuk aplikasi Laravel, pola yang cukup umum adalah:

Request
   ↓
Laravel
   ↓
Cek Cache
   │
   ├── HIT ──────→ Return Data
   │
   └── MISS
        ↓
    Query Database
        ↓
    Simpan Cache
        ↓
    Return Data

Implementasinya:

$data = Cache::remember(
    'some-data',
    600,
    fn () => Model::query()->get()
);

Ketika data berubah:

Cache::forget('some-data');

Pola sederhana ini sudah cukup untuk banyak kebutuhan caching.

Best Practice Laravel Cache

Beberapa praktik yang sebaiknya diterapkan:

1. Gunakan Cache untuk Data yang Tepat

Jangan meng-cache semua query.

2. Buat Cache Key yang Jelas

Contoh:

products:latest
products:category:10
product:123
user:45:profile

3. Tentukan TTL yang Masuk Akal

Sesuaikan dengan seberapa sering data berubah.

4. Pikirkan Cache Invalidation

Ketahui kapan cache harus dihapus atau diperbarui.

5. Gunakan remember() untuk Cache-Aside

Contoh:

Cache::remember(
    'products',
    600,
    fn () => Product::latest()->get()
);

6. Pertimbangkan Redis untuk Aplikasi yang Membutuhkan Cache Cepat

Redis dapat menjadi pilihan ketika kebutuhan cache semakin besar.

7. Monitor Cache Hit dan Miss

Cache yang jarang digunakan atau terlalu sering expired mungkin tidak memberikan manfaat yang diharapkan.

8. Jangan Menyimpan Data Sensitif Sembarangan

Pertimbangkan keamanan data sebelum memasukkannya ke cache, terutama jika cache store digunakan bersama oleh beberapa aplikasi atau environment.

Kapan Sebaiknya Menggunakan Laravel Cache?

Laravel Cache cocok digunakan ketika:

  • Query database sering dijalankan
  • Data relatif jarang berubah
  • Query membutuhkan waktu cukup lama
  • Data digunakan oleh banyak request
  • Aplikasi mengambil data dari API eksternal
  • Perhitungan tertentu membutuhkan resource besar
  • Aplikasi memiliki traffic tinggi

Contoh yang umum:

$categories = Cache::remember(
    'categories',
    3600,
    fn () => Category::orderBy('name')->get()
);

Kategori biasanya tidak berubah setiap detik, sehingga menyimpan hasil query selama beberapa waktu dapat mengurangi pekerjaan database.

Kapan Tidak Perlu Menggunakan Cache?

Tidak semua data perlu di-cache.

Misalnya query sederhana:

$user = User::find($id);

Jika query tersebut menggunakan index yang tepat dan execution time sangat kecil, manfaat caching mungkin tidak signifikan.

Caching juga kurang cocok jika data:

  • Harus selalu real-time
  • Sangat sering berubah
  • Jarang dibaca
  • Biaya mengambil ulang datanya sangat kecil

Dalam kasus tersebut, kompleksitas cache invalidation bisa lebih besar daripada manfaatnya.

Kesimpulan

Laravel Cache adalah salah satu cara efektif untuk meningkatkan performa aplikasi dengan mengurangi pekerjaan yang harus dilakukan berulang kali.

Pola paling sederhana adalah menggunakan:

Cache::remember(
    'products',
    600,
    fn () => Product::latest()->get()
);

Laravel akan menggunakan data dari cache jika tersedia. Jika belum tersedia, Laravel menjalankan query, menyimpan hasilnya, kemudian mengembalikannya.

Beberapa hal penting yang perlu diperhatikan:

  • Gunakan cache untuk data yang sering dibaca.
  • Tentukan TTL sesuai karakteristik data.
  • Gunakan cache key yang konsisten.
  • Jangan lupa melakukan invalidasi ketika data berubah.
  • Jangan cache semua data tanpa mempertimbangkan manfaatnya.
  • Gunakan Redis jika kebutuhan caching aplikasi semakin besar.

Pada aplikasi Laravel yang mulai berkembang, kombinasi database optimization + Eager Loading + Cache + Redis dapat memberikan peningkatan performa yang signifikan.

Yang paling penting, jangan menggunakan cache hanya karena “cache lebih cepat”. Ukur terlebih dahulu bottleneck aplikasi, lalu gunakan caching pada bagian yang memang memberikan dampak nyata terhadap performa.