Redis is an in-memory data store that makes Laravel applications faster by caching expensive queries, HTML fragments, and session data. When configured correctly, Redis reduces database load and improves response times under traffic spikes.
Installing and Configuring Redis
Install the Redis server and PHP redis extension on your server or use a managed service like AWS ElastiCache.
Laravel connects through config/database.php redis section and environment variables.
Step 1: Install Redis and the PHP extension
On Ubuntu run sudo apt install redis-server php-redis. Verify with redis-cli ping returning PONG.
For Docker, add a redis service and point REDIS_HOST to the container hostname.
sudo apt install redis-server php-redis
redis-cli ping
Step 2: Set cache and session drivers
In .env set CACHE_STORE=redis and SESSION_DRIVER=redis for unified in-memory storage.
Separate databases using REDIS_CACHE_DB=1 and REDIS_DB=0 to isolate sessions from cache keys.
CACHE_STORE=redis
SESSION_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
Step 3: Install Predis or phpredis
Laravel works with the phpredis extension natively. Alternatively composer require predis/predis for pure PHP client.
phpredis is faster at scale. Ensure extension is loaded: php -m | grep redis.
composer require predis/predis
Step 4: Verify connectivity with Tinker
Run Cache::put('ping', 'pong', 60) and Cache::get('ping') in php artisan tinker.
If connection fails, check REDIS_PASSWORD, bind address in redis.conf, and firewall rules on port 6379.
Cache::put('ping', 'pong', 60);
Cache::get('ping');
Cache Facade Patterns
The Cache facade provides get, put, remember, forget, and flush operations with TTL support.
Use descriptive key prefixes like products:list:page:1 so debugging with redis-cli KEYS is manageable.
Step 1: Cache query results with remember()
Wrap expensive queries: Cache::remember('dashboard.stats', 300, fn() => DB::table(…)->get()).
The closure runs only on cache miss. TTL is in seconds. Choose TTL based on acceptable staleness.
$stats = Cache::remember('dashboard.stats', 300, function () {
return DashboardService::computeStats();
});
Step 2: Invalidate cache on writes
After updating a product, call Cache::forget('product.'.$id) or flush tagged entries.
Pair observers or event listeners with cache invalidation so users never see stale prices or inventory counts.
Cache::forget('product.'.$product->id);
Step 3: Use cache tags for grouped invalidation
Cache::tags(['products'])->put($key, $value, $ttl) groups related keys. Flush all product cache with Cache::tags(['products'])->flush().
Tags require Redis or Memcached. They are unavailable on file or database cache drivers.
Cache::tags(['products'])->put('list', $products, 3600);
Cache::tags(['products'])->flush();
Step 4: Add HTTP cache headers at the edge
Combine application cache with CDN caching for public pages. Set ETag or Cache-Control in middleware.
Application Redis cache and HTTP cache solve different layers. Use both for maximum throughput.
- Redis for computed data
- CDN for static assets
Production Redis Best Practices
Production Redis needs persistence policies, memory limits, and monitoring to stay reliable.
Horizon and Laravel Telescope help observe queue and cache behavior in real time.
Step 1: Configure maxmemory and eviction
Set maxmemory in redis.conf and choose an eviction policy like allkeys-lru when memory is full.
Monitor used_memory with redis-cli INFO memory. Scale vertically or add replicas before evictions hurt hit rate.
maxmemory 256mb
maxmemory-policy allkeys-lru
Step 2: Use Redis for queues with Horizon
Set QUEUE_CONNECTION=redis and install laravel/horizon for dashboard and worker management.
Run php artisan horizon in production supervised by systemd. Horizon balances workers across queues.
composer require laravel/horizon
php artisan horizon:install
Step 3: Serialize carefully
Eloquent collections cache well but watch for large payloads. Cache IDs and re-query with eager loading when objects are huge.
Use Cache::rememberForever() only for truly static reference data like country lists.
Cache::rememberForever('countries', fn () => Country::orderBy('name')->get());
Step 4: Benchmark before and after
Use Laravel Debugbar or clockwork to compare query counts with cache on and off.
Document cache keys and TTLs in your runbook so on-call engineers can flush the right keys during incidents.
php artisan cache:clear
Aadyanex builds production-ready Laravel applications with clean architecture, secure APIs, and long-term support.
