If your Laravel app slows down when 50 users hit it simultaneously, the problem is not the framework. It's likely the session, cache, or queue driver you chose. File, database, array: they work for development, but in production they choke. We, at Meteora Web, see this every day in projects coming to us for consulting. The solution is Redis, and Laravel integrates it perfectly. Let's see how to configure it and use it for sessions, cache, and queues, with examples you can copy and deploy immediately.
Why Redis with Laravel is a no-brainer
Redis is an in-memory data store, incredibly fast. In Laravel, you can use it as driver for three critical systems: sessions, cache, and queues. When a user makes a request, a session read from file or database adds latency. File system cache works but doesn't scale across multiple servers. Database queues become a bottleneck. Redis solves all three with a single service, persistent if you want, with sub-millisecond latency.
We have chosen Redis for clients with custom WooCommerce e-commerce and proprietary Laravel platforms. The result? Response times cut in half, queues processed in real time, shared sessions between servers. And the configuration is simpler than you think.
Sponsored Protocol
Configuring Redis in Laravel
Install and start Redis on your server
First, you need Redis installed. On Ubuntu/Debian:
sudo apt update
sudo apt install redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-server
Verify it works:
redis-cli ping
# Output: PONG
For advanced configuration (persistence, password, ports), see the official Redis documentation.
Configure Laravel to use Redis
Laravel already includes Redis support via predis or phpredis. We recommend phpredis for better performance. Install it:
sudo apt install php8.3-redis # adjust to your PHP version
Then in your project's .env:
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
In the config/database.php file you'll already find the redis section. We customize it like this:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
],
Notice the separation between default and cache connections: we use different Redis databases to avoid key collisions.
Sponsored Protocol
Using Redis for Sessions
In your .env set:
SESSION_DRIVER=redis
Laravel will now store session data in Redis. The benefits are huge: shared sessions across multiple server instances (useful for load balancing) and near-instant read/write speed. Zero file I/O, zero database queries.
Common mistake: forgetting to set a unique prefix for Redis keys. To avoid collisions, add in .env:
SESSION_CONNECTION=default
# or, if you want a separate connection
# SESSION_CONNECTION=sessions
We at Meteora Web always verify that sessions survive a deploy. Redis is persistent (if configured) but we recommend enabling RDB or AOF in production to avoid losing sessions on crash. See the Redis persistence guide.
Using Redis for Cache
Driver and Stores
Set in .env:
Sponsored Protocol
CACHE_DRIVER=redis
Laravel supports cache tags with Redis. Tags let you invalidate groups of keys. Practical example:
// Store with tags
Cache::tags(['products', 'prices'])->put('product_123', $data, 3600);
// Retrieve
$product = Cache::tags(['products', 'prices'])->get('product_123');
// Flush all prices
Cache::tags(['prices'])->flush();
This is powerful: you can update an entire category without knowing all keys. Redis handles tags with sets.
TTL and Cache Busting
Set appropriate expiration times. For rarely changing data (e.g., configurations, product lists), use long TTLs. For volatile data, short TTLs. We use a pattern: cache forever with explicit invalidation via events (e.g., model saved).
// App/Providers/EventServiceProvider.php
protected $listen = [
'eloquent.saved: App\Models\Product' => [
'App\Listeners\ClearProductCache',
],
];
// App/Listeners/ClearProductCache.php
public function handle(Product $product)
{
Cache::tags(['products'])->flush();
}
Using Redis for Queues
Queues in Laravel with database driver work, but don't scale. Each job causes an insert and an update query. With Redis, everything is in memory, much faster.
Configuration in .env:
Sponsored Protocol
QUEUE_CONNECTION=redis
Then run the worker:
php artisan queue:work redis --sleep=3 --tries=3
For multiple queues with priority, define in config/queue.php:
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
'after_commit' => false,
],
],
You can specify multiple queues: high, low, default. Then in your jobs use:
ProcessPodcast::dispatch()->onQueue('high');
And start workers on specific queues:
php artisan queue:work redis --queue=high,default
Laravel Horizon for advanced management
For serious projects, use Horizon. It's a control panel for Redis queues, built by Laravel. Installation:
composer require laravel/horizon
php artisan horizon:install
Configure config/horizon.php to define workers, balancing, notifications. Then start:
php artisan horizon
Horizon gives you metrics, failures, speed in real time. We use it on every Laravel project that processes more than 10 jobs per minute.
Common pitfalls and how to avoid them
- Lost connection: Redis is not running. Check with
systemctl status redisand enable auto-restart. - Out of memory: Redis has limited memory. Configure
maxmemoryandmaxmemory-policy(e.g.,allkeys-lru). - Key collision: Use unique prefixes for each app (see
REDIS_PREFIX). - Queue worker crashes: Use
supervisorto keep workers alive. We set it up in 5 minutes.
Monitoring and performance
Use redis-cli MONITOR to see commands in real time. On Laravel, install laravel/telescope to trace Redis queries and queue jobs. A handy command to see keys:
Sponsored Protocol
redis-cli --scan --pattern 'laravel_*'
In summary — what to do now
- Install Redis on your server and verify with
redis-cli ping. - Set
SESSION_DRIVER=redis,CACHE_DRIVER=redis,QUEUE_CONNECTION=redisin your.env. - Configure separate Redis databases for cache (
cacheconnection) and for sessions/queues (default). - If you use queues, install Horizon and configure it with supervisor.
- Test everything: open the site, verify sessions work, cache is populated, jobs are processed.
Redis is not an option for Laravel in production; it's the professional choice. We, at Meteora Web, use it in every performing project. If you want to dive deeper into the caching ecosystem, read our pillar guide on Redis and Caching Strategies. For related topics, see also Linux for Developers and Sysadmins.