LAB -

Laravel/OctoberCMS and Redis Cluster Integration

Robert Rotter Oct 14, 2025

Redis Cluster Integration with Laravel 12 / OctoberCMS v3 (phpredis driver)


Running Redis Cluster on Kubernetes with Laravel 12 / October CMS v3 isn’t straightforward. Several subtle misconfigurations make it silently fall back to single-node mode or fail authentication. Below is the final working configuration, followed by the gotchas and optional advanced settings that solve every related error.

Final Working Configuration

Environment Variables (.env)

REDIS_CLIENT : "phpredis" (default value)
REDIS_PORT : "6379" (default value)
CACHE_DRIVER : "redis"
SESSION_DRIVER : "redis"
SESSION_CONNECTION : "session"
REDIS_CLUSTER_SERVERS : "redis-cluster-0.redis-cluster-headless.redis.svc.cluster.local:6379,redis-cluster-1.redis-cluster-headless.redis.svc.cluster.local:6379,..."
REDIS_PASSWORD : "your password"
REDIS_CACHE_DB: "1"
REDIS_SESSION_DB: "2"

Database Configuration (config/database.php)

'redis' => [
   'client' => env('REDIS_CLIENT', 'phpredis'),
   'options' => [
       'cluster' => env('REDIS_CLUSTER', 'redis'),
       'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
       'password' => env('REDIS_PASSWORD')
   ],
   'clusters' => [
       'default' => array_map(function ($server) {
       [$host, $port] = explode(':', $server);
       return [
           'host' => $host,
           'password' => env('REDIS_PASSWORD'),
           'port' => $port
       ];
       }, explode(',', env('REDIS_CLUSTER_SERVERS', '127.0.0.1:6379'))),
   ],
]

How to verify

php artisan tinker
>>> config('database.redis.options.cluster')
=> "redis"
>>> Redis::connection()->client()->info()['cluster_enabled']
=> "1"

If cluster_enabled returns 1, cluster mode is active.

Things to look out for

“cluster = redis” + phpredis and don't try using REDIS_HOST

Laravel switches to Redis cluster (in config/database.php) only when :

'client'  => 'phpredis',
'options' => ['cluster' => 'redis']

If either is missing (or cached), Laravel falls back to 127.0.0.1:6379.

Additionally: Don’t try setting REDIS_HOST to a single cluster service or point to a node via headless service (e.g. redis-cluster.redis.svc.cluster.local). phpredis cluster discovery won’t work that way, it must receive the full node list through the clusters array.

Fix: Always define cluster nodes via your own REDIS_CLUSTER_SERVERS and make sure you clear configs:

php artisan config:clear && php artisan cache:clear
"clusters" block must be defined

Laravel expects (in config/database.php) all cluster nodes under :

'redis.clusters.default/cache/session'

Each node requires a host + port (typically your Redis StatefulSet DNS entries).

remove "default" and "cache" single-node blocks

If default or cache arrays exist under redis, Laravel ignores the cluster configuration and connects to 127.0.0.1.

Fix: Delete them entirely, only clusters should remain.

the undocumented final fix, "password" in options

Even when cluster nodes and credentials were correct, phpredis failed during cluster discovery with:

RedisClusterException: Couldn't map cluster keyspace using any provided seed

This happens because phpredis ignores per-node passwords when creating a Redis cluster instance. Laravel never passes a global password, so authentication fails before the keyspace map can be fetched.

Fix:

Add the password at the top level in options, applied to all cluster connections:

'redis' => [
   …
   'options' => [
       …
       'password' => env('REDIS_PASSWORD'),
   …
   ],

Reference: phpredis #1533 undocumented in Laravel or OctoberCMS.

separate cache and session
REDIS_CACHE_DB: "1"
REDIS_SESSION_DB: "2"

Use different redis index (db) to separate CACHE and SESSION and allow one to be flushed without the other.

bonus / optional settings

For production deployments, you can further tune Redis Cluster connectivity and performance:

'redis' => [
   'client' => env('REDIS_CLIENT', 'phpredis'),
   'options' => [
       'cluster' => env('REDIS_CLUSTER', 'redis'),
       'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
       'password' => env('REDIS_PASSWORD'),
       'replication' => true,
       'persistent' => true,
   ],
   'clusters' => [
       'default' => array_map(function ($server) {
       [$host, $port] = explode(':', $server);
       return [
           'host' => $host,
           'password' => env('REDIS_PASSWORD'),
           'port' => $port,
           'persistent' => true,
           'scheme'   => env('REDIS_SCHEME', 'tcp'),
           'database' => env('REDIS_CACHE_DB', 0),
           'read_write_timeout' => 30,
       ];
       }, explode(',', env('REDIS_CLUSTER_SERVERS', '127.0.0.1:6379'))),

       'cache' => array_map(function ($server) {
       [$host, $port] = explode(':', $server);
       return [
           'host' => $host,
           'password' => env('REDIS_PASSWORD'),
           'port' => $port,
           'persistent' => true,
           'scheme'   => env('REDIS_SCHEME', 'tcp'),
           'database' => env('REDIS_CACHE_DB', 0),
           'read_write_timeout' => 30,
       ];
       }, explode(',', env('REDIS_CLUSTER_SERVERS', '127.0.0.1:6379'))),

       'session' => array_map(function ($server) {
       [$host, $port] = explode(':', $server);
       return [
           'host' => $host,
           'password' => env('REDIS_PASSWORD'),
           'port' => $port,
           'persistent' => true,
           'scheme'   => env('REDIS_SCHEME', 'tcp'),
           'database' => env('REDIS_SESSION_DB', 0),
           'read_write_timeout' => 30,
       ];
       }, explode(',', env('REDIS_CLUSTER_SERVERS', '127.0.0.1:6379'))),
   ],
]

These options improve socket reuse, reduce connection overhead, and enable replica reads for large cluster deployments.

results

After applying these fixes, OctoberCMS v3 / Laravel 12 connected cleanly to a 6-node Redis Cluster, distributed cache operations correctly, and eliminated all:

Connection refused
RedisClusterException: Couldn't map cluster keyspace using any provided seed
MOVED

By implementing this global password directive and adhering to the checklist, you ensure your infrastructure operates as designed. If your project faces a unique architectural challenge, our senior specialists are ready to help.

Contact us to discuss your project.

Subscribe to our newsletter

Rest assured we will not misuse your email