Pertama kali saya coba pakai Redis di project PHP, hasilnya bikin kaget. Response time yang tadinya 800ms langsung turun jadi 50ms. Gila kan? Sejak itu, hampir semua project saya yang butuh performa tinggi pasti pakai Redis sebagai layer caching.
Redis itu singkatan dari Remote Dictionary Server. Secara sederhana, ini adalah in-memory data store yang super cepat karena data disimpan di RAM, bukan di disk seperti MySQL. Cocok banget buat caching query database, session management, rate limiting API, dan banyak lagi.
Saya pernah handle project e-commerce yang traffic-nya naik 10x pas flash sale. Tanpa caching, MySQL langsung choke. Query yang biasanya 20ms tiba-tiba jadi 2 detik karena tabel products punya 500 ribu row. Setelah pasang Redis, beban MySQL turun drastis karena data produk yang sering diakses disimpan di RAM.
Keunggulan Redis dibanding cara caching lain:
Proses installnya gampang banget. Saya pakai Ubuntu 24.04 LTS di contoh ini, tapi langkahnya mirip untuk versi Ubuntu lainnya.
Update dulu package list dan install Redis:
sudo apt update && sudo apt upgrade -y
sudo apt install redis-server -y
Setelah install, cek status Redis:
sudo systemctl status redis-server
Kalau outputnya active (running), berarti Redis sudah jalan. Tapi jangan senang dulu, masih ada beberapa konfigurasi penting yang perlu di-setup.
File konfigurasi Redis ada di /etc/redis/redis.conf. Ada beberapa setting yang wajib kamu ubah sebelum dipakai di production:
Defaultnya Redis listen di 127.0.0.1 (hanya local). Kalau aplikasi PHP kamu di server yang sama, ini sudah cukup. Tapi kalau beda server, kamu perlu bind ke IP server:
# Edit redis.conf
sudo nano /etc/redis/redis.conf
# Cari baris bind dan ubah:
bind 127.0.0.1 ::1
# Kalau perlu akses dari server lain:
# bind 127.0.0.1 ::1 192.168.1.100
Jangan pernah jalanin Redis tanpa password di production. Generate password yang kuat:
# Generate random password
openssl rand -base64 32
# Tambahkan di redis.conf
requirepass YourSuperStrongPassword123!
Ini bagian paling penting. Redis menyimpan semua data di RAM, jadi kamu harus batasi berapa banyak memory yang boleh dipakai:
# Batasi memory ke 256MB
maxmemory 256mb
# Eviction policy: hapus data yang paling jarang dipakai
maxmemory-policy allkeys-lru
Ada beberapa eviction policy yang bisa dipilih:
Setelah ubah config, restart Redis:
sudo systemctl restart redis-server
Redis sering kasih warning tentang kernel settings. Fix dengan cara ini:
# Set vm.overcommit_memory
echo 'vm.overcommit_memory = 1' | sudo tee -a /etc/sysctl.conf
# Disable THP (Transparent Huge Pages)
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
# Increase somaxconn
echo 'net.core.somaxconn = 65535' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Redis server sudah jalan, sekarang kita butuh PHP extension untuk bisa konek dari kode PHP. Ada dua cara: pakai phpredis (C extension, lebih cepat) atau predis (pure PHP, lebih fleksibel).
# Install via PECL
sudo pecl install redis
# Tambahkan ke php.ini
echo "extension=redis.so" | sudo tee /etc/php/8.3/mods-available/redis.ini
sudo phpenmod redis
# Restart PHP-FPM
sudo systemctl restart php8.3-fpm
# Verifikasi
php -m | grep redis
composer require predis/predis
Di project CodeIgniter 4, saya lebih suka pakai Predis karena instalasinya gampang dan tidak butuh akses root ke server. Tapi kalau performa adalah prioritas utama, phpredis lebih cepat sekitar 20-30%.
Sekarang bagian yang seru: menulis kode. Ini contoh basic caching pattern yang sering saya pakai:
<?php
// Koneksi ke Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('YourSuperStrongPassword123!');
// Cek apakah data ada di cache
$cacheKey = 'products:featured';
$cachedData = $redis->get($cacheKey);
if ($cachedData) {
// Cache hit - langsung pakai data dari Redis
$products = json_decode($cachedData, true);
echo "Data dari cache!";
} else {
// Cache miss - query database
$pdo = new PDO('mysql:host=localhost;dbname=shop', 'user', 'pass');
$stmt = $pdo->query("SELECT * FROM products WHERE featured = 1 LIMIT 20");
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Simpan ke Redis, expired dalam 1 jam
$redis->setex($cacheKey, 3600, json_encode($products));
echo "Data dari database, disimpan ke cache!";
}
print_r($products);
Pola ini disebut Cache-Aside Pattern. Konsepnya simpel:
Di CI4, integrasi Redis bisa dilakukan di beberapa level. Ini cara yang paling clean menurut pengalaman saya:
Edit file app/Config/App.php:
<?php
// app/Config/App.php
public string $sessionDriver = 'CodeIgniter\Session\Handlers\RedisHandler';
public string $sessionSavePath = 'tcp://127.0.0.1:6379?auth=YourSuperStrongPassword123!';
public int $sessionExpiration = 7200;
Dengan ini, session user otomatis disimpan di Redis. Proses login, cart, flash messages semuanya jadi lebih cepat dibanding pakai file-based session.
Buat library cache yang bisa dipakai di mana saja:
<?php
// app/Libraries/RedisCache.php
namespace App\Libraries;
class RedisCache
{
private $redis;
private $prefix = 'ci4:';
public function __construct()
{
$this->redis = new \Redis();
$this->redis->connect('127.0.0.1', 6379);
$this->redis->auth('YourSuperStrongPassword123!');
}
public function get(string $key)
{
$data = $this->redis->get($this->prefix . $key);
return $data ? json_decode($data, true) : null;
}
public function set(string $key, $value, int $ttl = 3600)
{
return $this->redis->setex(
$this->prefix . $key,
$ttl,
json_encode($value)
);
}
public function delete(string $key)
{
return $this->redis->del($this->prefix . $key);
}
public function flush()
{
// Hapus hanya key dengan prefix project kita
$keys = $this->redis->keys($this->prefix . '*');
if (!empty($keys)) {
$this->redis->del($keys);
}
}
// Cache dengan callback - praktis banget
public function remember(string $key, int $ttl, callable $callback)
{
$cached = $this->get($key);
if ($cached !== null) {
return $cached;
}
$data = $callback();
$this->set($key, $data, $ttl);
return $data;
}
}
Pakai di controller:
<?php
namespace App\Controllers;
use App\Libraries\RedisCache;
class Product extends BaseController
{
public function index()
{
$cache = new RedisCache();
// Satu baris untuk caching! Sangat clean
$products = $cache->remember('products:all', 1800, function() {
$model = new \App\Models\ProductModel();
return $model->where('active', 1)->findAll();
});
return view('products/index', ['products' => $products]);
}
public function update($id)
{
// Update product...
// Invalidate cache setelah update
$cache = new RedisCache();
$cache->delete('products:all');
$cache->delete("products:{$id}");
return redirect()->to('/products');
}
}
Method remember() ini yang paling sering saya pakai. Cek cache, kalau tidak ada jalankan callback, simpan hasilnya. Simple dan tidak perlu tulis logic caching berulang-ulang.
Kalau kamu bikin API, rate limiting itu wajib hukumnya. Redis sangat cocok untuk ini karena operasinya atomic dan cepat:
<?php
function checkRateLimit(string $ip, int $maxRequests = 60, int $windowSeconds = 60): bool
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$key = "ratelimit:{$ip}";
// Increment counter
$current = $redis->incr($key);
// Set expiry pada request pertama
if ($current === 1) {
$redis->expire($key, $windowSeconds);
}
// Cek apakah melebihi limit
if ($current > $maxRequests) {
return false; // Rate limit exceeded
}
return true; // Masih dalam limit
}
// Di middleware atau controller:
$clientIp = $this->request->getIPAddress();
if (!checkRateLimit($clientIp, 60, 60)) {
return $this->response->setStatusCode(429)->setJSON([
'error' => 'Too many requests. Try again in 60 seconds.'
]);
}
Redis punya CLI tool yang sangat berguna untuk monitoring:
# Masuk ke Redis CLI
redis-cli -a YourSuperStrongPassword123!
# Cek info server
INFO server
# Cek memory usage
INFO memory
# Cek statistik hit/miss
INFO stats
# Monitor command secara real-time
MONITOR
# Cek semua key yang ada
KEYS *
# Cek TTL key tertentu
TTL products:featured
# Cek ukuran data
DEBUG OBJECT products:featured
Untuk monitoring yang lebih serius, kamu bisa pakai redis-exporter dengan Prometheus + Grafana. Tapi untuk awal, redis-cli INFO sudah cukup.
Saya sudah cukup lama pakai Redis, dan ini masalah yang paling sering saya temui:
Kalau cache expired dan 1000 request datang barengan, semuanya langsung ke database. Solusinya pakai locking:
<?php
public function getWithLock(string $key, int $ttl, callable $callback)
{
$data = $this->get($key);
if ($data !== null) {
return $data;
}
$lockKey = $key . ':lock';
// Coba ambil lock (setnx = set if not exists)
if ($this->redis->setnx($lockKey, 1)) {
$this->redis->expire($lockKey, 10); // Lock expired 10 detik
try {
$data = $callback();
$this->set($key, $data, $ttl);
return $data;
} finally {
$this->redis->del($lockKey);
}
}
// Kalau tidak dapat lock, tunggu dan retry
usleep(100000); // 100ms
return $this->getWithLock($key, $ttl, $callback);
}
Ini masalah klasik. Data di database sudah diubah, tapi cache masih data lama. Solusi: selalu invalidate cache setelah write operation. Buat helper method dan konsisten pakai di mana-mana.
Pakai konvensi penamaan yang konsisten:
# Format: {module}:{entity}:{id}:{attribute}
products:detail:123
products:list:featured
users:session:abc123
api:ratelimit:192.168.1.1
Setiap key harus punya TTL. Kalau tidak, cache akan terus menumpuk sampai RAM habis. Default TTL yang biasa saya pakai:
Ini hasil benchmark sederhana yang saya buat di VPS 2GB RAM dengan 50.000 row di tabel products:
Peningkatan performa hampir 38x lipat. Dan ini cuma untuk satu tabel. Kalau aplikasinya punya banyak tabel yang sering di-query, efeknya makin terasa.
Redis itu game changer untuk aplikasi PHP yang butuh performa tinggi. Installasi dan konfigurasinya relatif mudah, tapi dampaknya luar biasa besar. Mulai dari caching query database sampai session management, Redis bisa handle semuanya dengan cepat dan efisien.
Kalau kamu baru mulai, saran saya: pasang Redis di project yang paling bermasalah dengan performa dulu. Rasakan sendiri bedanya. Setelah itu, saya yakin kamu akan ketagihan dan mulai pakai Redis di semua project.
Satu hal yang perlu diingat: Redis itu bukan pengganti database. Ini adalah layer tambahan untuk mempercepat akses data. Tetap optimasi query database kamu, tambah index yang tepat, dan pakai Redis sebagai pelengkap, bukan solusi utama.