From 9a86031927a9e9302209dea95955d838adbcaf53 Mon Sep 17 00:00:00 2001 From: Roberto Luna-Rojas Date: Sat, 4 Jul 2026 21:43:48 -0400 Subject: [PATCH 1/5] feat(database): Add Valkey (GLIDE) connection configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a "valkey" connection block in config/database.php backed by the valkey-glide client. Every option falls back to its matching REDIS_* value, so existing Redis apps can adopt Valkey with zero new config — either by switching CACHE_STORE=valkey or setting VALKEY_FROM_REDIS=true to route existing "redis" bindings through Valkey transparently. Expose Valkey-native GLIDE capabilities (AZ affinity, IAM auth, reconnect strategy, client-side caching, compression, OpenTelemetry) as optional, default-off keys, plus cluster and TLS support. Add a valkey service to docker-compose.yml, with commented-out cluster nodes for local multi-node testing. Signed-off-by: Roberto Luna-Rojas --- config/database.php | 134 ++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 31 ++++++++++ 2 files changed, 165 insertions(+) diff --git a/config/database.php b/config/database.php index dcfe3f033179..defa3104abb2 100644 --- a/config/database.php +++ b/config/database.php @@ -191,4 +191,138 @@ ], + /* + |-------------------------------------------------------------------------- + | Valkey Databases + |-------------------------------------------------------------------------- + | + | Valkey is a Linux Foundation, BSD-licensed key-value store forked from + | Redis and fully wire-protocol compatible. This integration uses the + | valkey-glide client. Every option below falls back to the matching + | REDIS_* value, so if your app already uses Redis you can adopt Valkey + | with zero new configuration: + | + | • Set CACHE_STORE=valkey (and/or QUEUE_CONNECTION, SESSION_DRIVER), or + | • Keep CACHE_STORE=redis and set VALKEY_FROM_REDIS=true to route the + | existing "redis" bindings through Valkey transparently. + | + */ + + 'valkey' => [ + + // When true, the existing "redis" cache store / queue / session + // drivers (and Redis:: facade calls) transparently route through the + // Valkey (GLIDE) backend — keep CACHE_STORE=redis for a zero-config swap. + 'from_redis' => env('VALKEY_FROM_REDIS', false), + + 'client' => env('VALKEY_CLIENT', 'valkey_glide'), + + 'options' => [ + 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER')), + 'prefix' => env('VALKEY_PREFIX', env('REDIS_PREFIX')), + 'persistent' => env('VALKEY_PERSISTENT', env('REDIS_PERSISTENT')), + ], + + 'default' => [ + 'url' => env('VALKEY_URL', env('REDIS_URL')), + 'host' => env('VALKEY_HOST', env('REDIS_HOST')), + 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), + 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), + 'port' => env('VALKEY_PORT', env('REDIS_PORT')), + 'database' => env('VALKEY_DB', env('REDIS_DB')), + 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES')), + 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM')), + 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE')), + 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP')), + ], + + 'cache' => [ + 'url' => env('VALKEY_URL', env('REDIS_URL')), + 'host' => env('VALKEY_HOST', env('REDIS_HOST')), + 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), + 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), + 'port' => env('VALKEY_PORT', env('REDIS_PORT')), + 'database' => env('VALKEY_CACHE_DB', env('REDIS_CACHE_DB')), + 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES')), + 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM')), + 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE')), + 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP')), + ], + + 'use_tls' => env('VALKEY_TLS', false), + 'read_from' => env('VALKEY_READ_FROM', 'primary'), // primary | prefer_replica | az_affinity | any + 'request_timeout' => env('VALKEY_REQUEST_TIMEOUT', 250), + 'connection_timeout' => env('VALKEY_CONNECTION_TIMEOUT', 250), + 'client_name' => env('VALKEY_CLIENT_NAME'), + 'lazy_connect' => env('VALKEY_LAZY_CONNECT', false), + 'inflight_requests_limit' => env('VALKEY_INFLIGHT_LIMIT', 1000), + + /* + |---------------------------------------------------------------------- + | Valkey-Native Options (GLIDE) + |---------------------------------------------------------------------- + | + | The keys above are Redis-compatible and "just work" with existing + | REDIS_* environment variables. The options below expose GLIDE's + | Valkey-native capabilities — all are optional and default off/unset. + | Add any of these keys to a connection array to enable them: + | + | + | // Availability-zone affinity (same-AZ replica reads) + | 'az_affinity' => [ + | 'enabled' => env('VALKEY_AZ_AFFINITY', false), + | 'az' => env('VALKEY_AZ'), + | ], + | + | // AWS ElastiCache / MemoryDB IAM auth + | 'iam_config' => null, // Set to array to enable + | + | // Reconnect / backoff strategy + | 'reconnect_strategy' => [ + | 'num_of_retries' => env('VALKEY_RECONNECT_RETRIES', 3), + | 'factor' => env('VALKEY_RECONNECT_FACTOR', 2), + | 'exponent_base' => env('VALKEY_RECONNECT_EXP_BASE', 2), + | ], + | + | // Client-side caching (server-assisted invalidation) + | 'client_side_cache' => [ + | 'enabled' => env('VALKEY_CSC_ENABLED', false), + | 'max_size' => env('VALKEY_CSC_MAX_SIZE', 10000), + | ], + | + | // Native payload compression (experimental) + | 'compression' => [ + | 'enabled' => env('VALKEY_COMPRESSION', false), + | 'algorithm' => env('VALKEY_COMPRESSION_ALGO', 'lz4'), + | ], + | + */ + + 'clusters' => [ + + // 'default' => [ + // ['host' => '10.0.0.1', 'port' => 7000], + // ['host' => '10.0.0.2', 'port' => 7001], + // ['host' => '10.0.0.3', 'port' => 7002], + // ], + // 'options' => [ + // 'read_from' => 'prefer_replica', + // 'use_tls' => true, + // 'az_affinity' => ['enabled' => true, 'az' => 'us-east-1a'], + // ], + + ], + + 'otel' => [ + 'enabled' => env('VALKEY_OTEL_ENABLED', false), + 'endpoint' => env('VALKEY_OTEL_ENDPOINT'), + 'traces' => ['enabled' => true, 'sample_percentage' => env('VALKEY_OTEL_SAMPLE_PCT', 1)], + 'metrics' => ['enabled' => true], + 'flush_interval_ms' => env('VALKEY_OTEL_FLUSH_MS', 5000), + ], + + 'register_phpredis_aliases' => env('VALKEY_REGISTER_ALIASES', true), + + ], + ]; diff --git a/docker-compose.yml b/docker-compose.yml index 06f7fee2455d..0c423e928c98 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -77,3 +77,34 @@ services: # - redis-cluster-2 # command: sh -c 'redis-cli --cluster create redis-cluster-0:7000 redis-cluster-1:7001 redis-cluster-2:7002 --cluster-replicas 0 --cluster-yes || true' # restart: no + valkey: + image: valkey/valkey:9-alpine + ports: + - "6380:6379" + restart: always + # valkey-cluster-0: + # image: valkey/valkey:9-alpine + # ports: + # - "7100:7100" + # restart: always + # command: valkey-server --port 7100 --appendonly yes --cluster-enabled yes + # valkey-cluster-1: + # image: valkey/valkey:9-alpine + # ports: + # - "7101:7101" + # restart: always + # command: valkey-server --port 7101 --appendonly yes --cluster-enabled yes + # valkey-cluster-2: + # image: valkey/valkey:9-alpine + # ports: + # - "7102:7102" + # restart: always + # command: valkey-server --port 7102 --appendonly yes --cluster-enabled yes + # valkey-cluster-creator: + # image: valkey/valkey:9-alpine + # depends_on: + # - valkey-cluster-0 + # - valkey-cluster-1 + # - valkey-cluster-2 + # command: sh -c 'valkey-cli --cluster create valkey-cluster-0:7100 valkey-cluster-1:7101 valkey-cluster-2:7102 --cluster-replicas 0 --cluster-yes || true' + # restart: no From 895126bf95dcbd8027386537e22cf94914ea2b95 Mon Sep 17 00:00:00 2001 From: Roberto Luna-Rojas Date: Sat, 4 Jul 2026 21:43:52 -0400 Subject: [PATCH 2/5] chore(docker): Switch default dev database to Postgres Enable the postgres service on postgres:18-alpine and comment out the mysql and redis services, making Postgres the default local database for docker-compose development. Signed-off-by: Roberto Luna-Rojas --- docker-compose.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0c423e928c98..5e06c2cc8070 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,24 +10,24 @@ services: ports: - "11211:11211" restart: always - mysql: - image: mysql/mysql-server:5.7 - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: 1 - MYSQL_ROOT_PASSWORD: "" - MYSQL_DATABASE: "forge" - MYSQL_ROOT_HOST: "%" - ports: - - "3306:3306" - restart: always - # postgres: - # image: postgres:15 + # mysql: + # image: mysql/mysql-server:5.7 # environment: - # POSTGRES_PASSWORD: "secret" - # POSTGRES_DB: "forge" + # MYSQL_ALLOW_EMPTY_PASSWORD: 1 + # MYSQL_ROOT_PASSWORD: "" + # MYSQL_DATABASE: "forge" + # MYSQL_ROOT_HOST: "%" # ports: - # - "5432:5432" + # - "3306:3306" # restart: always + postgres: + image: postgres:18-alpine + environment: + POSTGRES_PASSWORD: "secret" + POSTGRES_DB: "forge" + ports: + - "5432:5432" + restart: always # mariadb: # image: mariadb:11 # environment: @@ -46,11 +46,11 @@ services: # ports: # - "1433:1433" # restart: always - redis: - image: redis:7.0-alpine - ports: - - "6379:6379" - restart: always + # redis: + # image: redis:7.0-alpine + # ports: + # - "6379:6379" + # restart: always # redis-cluster-0: # image: redis:7.0-alpine # ports: From 6a39edc6bcbf563d36c2b97be256ac830dcca9a2 Mon Sep 17 00:00:00 2001 From: Roberto Luna-Rojas Date: Sat, 4 Jul 2026 21:58:02 -0400 Subject: [PATCH 3/5] fix(database): Ensure Valkey config defaults match Redis parity The valkey connection fell back to bare env('REDIS_*') calls with no final default, so an app with no REDIS_* or VALKEY_* variables set resolved host, port, database, cluster, and retry options to null instead of the Redis driver's sensible defaults. Add the hardcoded defaults as the final fallback (127.0.0.1, 6379, db 0/1, cluster "redis", max_retries 3, etc.). Promote az_affinity from a commented example to a live option key so the availability-zone read affinity documented for read_from='az_affinity' is actually configurable, and add inline documentation comments for every option. Signed-off-by: Roberto Luna-Rojas --- config/database.php | 79 +++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/config/database.php b/config/database.php index defa3104abb2..2d1e70815102 100644 --- a/config/database.php +++ b/config/database.php @@ -215,46 +215,83 @@ // Valkey (GLIDE) backend — keep CACHE_STORE=redis for a zero-config swap. 'from_redis' => env('VALKEY_FROM_REDIS', false), + // Client implementation used to talk to Valkey (GLIDE-based driver). 'client' => env('VALKEY_CLIENT', 'valkey_glide'), 'options' => [ - 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER')), - 'prefix' => env('VALKEY_PREFIX', env('REDIS_PREFIX')), - 'persistent' => env('VALKEY_PERSISTENT', env('REDIS_PERSISTENT')), + // Cluster mode marker passed to the connector ("redis" or ""). + 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER', 'redis')), + // Key prefix applied to every command; defaults to the app slug. + 'prefix' => env('VALKEY_PREFIX', env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-')), + // Whether to reuse persistent connections between requests. + 'persistent' => env('VALKEY_PERSISTENT', env('REDIS_PERSISTENT', false)), ], 'default' => [ + // Full connection URL; overrides the discrete host/port keys below. 'url' => env('VALKEY_URL', env('REDIS_URL')), - 'host' => env('VALKEY_HOST', env('REDIS_HOST')), + // Hostname/IP of the Valkey primary node. + 'host' => env('VALKEY_HOST', env('REDIS_HOST', '127.0.0.1')), + // ACL username (Valkey 6+); null uses the default user. 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), + // Auth password / ACL secret. 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), - 'port' => env('VALKEY_PORT', env('REDIS_PORT')), - 'database' => env('VALKEY_DB', env('REDIS_DB')), - 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES')), - 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM')), - 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE')), - 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP')), + // TCP port of the Valkey server. + 'port' => env('VALKEY_PORT', env('REDIS_PORT', '6379')), + // Logical database index for general connection usage. + 'database' => env('VALKEY_DB', env('REDIS_DB', '0')), + // Max automatic command retries before failing. + 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES', 3)), + // Retry backoff strategy between attempts. + 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter')), + // Base backoff delay in milliseconds. + 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE', 100)), + // Maximum backoff delay cap in milliseconds. + 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP', 1000)), ], 'cache' => [ + // Full connection URL; overrides the discrete host/port keys below. 'url' => env('VALKEY_URL', env('REDIS_URL')), - 'host' => env('VALKEY_HOST', env('REDIS_HOST')), + // Hostname/IP of the Valkey primary node. + 'host' => env('VALKEY_HOST', env('REDIS_HOST', '127.0.0.1')), + // ACL username (Valkey 6+); null uses the default user. 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), + // Auth password / ACL secret. 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), - 'port' => env('VALKEY_PORT', env('REDIS_PORT')), - 'database' => env('VALKEY_CACHE_DB', env('REDIS_CACHE_DB')), - 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES')), - 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM')), - 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE')), - 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP')), + // TCP port of the Valkey server. + 'port' => env('VALKEY_PORT', env('REDIS_PORT', '6379')), + // Dedicated logical database index for the cache store. + 'database' => env('VALKEY_CACHE_DB', env('REDIS_CACHE_DB', '1')), + // Max automatic command retries before failing. + 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES', 3)), + // Retry backoff strategy between attempts. + 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter')), + // Base backoff delay in milliseconds. + 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE', 100)), + // Maximum backoff delay cap in milliseconds. + 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP', 1000)), ], + // Enable TLS/SSL for all connections in this group. 'use_tls' => env('VALKEY_TLS', false), - 'read_from' => env('VALKEY_READ_FROM', 'primary'), // primary | prefer_replica | az_affinity | any + // Read routing policy: primary | prefer_replica | az_affinity | any. + 'read_from' => env('VALKEY_READ_FROM', 'primary'), + // Availability-zone affinity for same-AZ replica reads. Takes effect + // when read_from is "az_affinity"; set the AZ your app runs in. + 'az_affinity' => [ + 'enabled' => env('VALKEY_AZ_AFFINITY', false), + 'az' => env('VALKEY_AZ'), + ], + // Per-request timeout in milliseconds. 'request_timeout' => env('VALKEY_REQUEST_TIMEOUT', 250), + // Connection establishment timeout in milliseconds. 'connection_timeout' => env('VALKEY_CONNECTION_TIMEOUT', 250), + // Optional client name reported to the server (CLIENT SETNAME). 'client_name' => env('VALKEY_CLIENT_NAME'), + // Defer connecting until the first command is issued. 'lazy_connect' => env('VALKEY_LAZY_CONNECT', false), + // Cap on concurrent in-flight requests per connection. 'inflight_requests_limit' => env('VALKEY_INFLIGHT_LIMIT', 1000), /* @@ -268,12 +305,6 @@ | Add any of these keys to a connection array to enable them: | | - | // Availability-zone affinity (same-AZ replica reads) - | 'az_affinity' => [ - | 'enabled' => env('VALKEY_AZ_AFFINITY', false), - | 'az' => env('VALKEY_AZ'), - | ], - | | // AWS ElastiCache / MemoryDB IAM auth | 'iam_config' => null, // Set to array to enable | From 5b8ca51298034c8a5b4962f61391a7500b9c7c15 Mon Sep 17 00:00:00 2001 From: Roberto Luna-Rojas Date: Sat, 4 Jul 2026 22:01:42 -0400 Subject: [PATCH 4/5] refactor(database): Simplify Valkey config to mirror Redis section The valkey block had grown far more verbose than the neighboring redis block, with per-key inline comments, a large commented native-options block, cluster examples, otel, and other keys beyond the driver's needs. Trim it to mirror the redis section's concise style: a doc-block header plus plain keys. Fold the Valkey-native options (use_tls, read_from, az_affinity) into the options array, matching how redis groups its own options. All REDIS_* fallbacks and sensible defaults are preserved. Signed-off-by: Roberto Luna-Rojas --- config/database.php | 124 +++----------------------------------------- 1 file changed, 7 insertions(+), 117 deletions(-) diff --git a/config/database.php b/config/database.php index 2d1e70815102..81cd07743a96 100644 --- a/config/database.php +++ b/config/database.php @@ -196,164 +196,54 @@ | Valkey Databases |-------------------------------------------------------------------------- | - | Valkey is a Linux Foundation, BSD-licensed key-value store forked from - | Redis and fully wire-protocol compatible. This integration uses the - | valkey-glide client. Every option below falls back to the matching - | REDIS_* value, so if your app already uses Redis you can adopt Valkey - | with zero new configuration: - | - | • Set CACHE_STORE=valkey (and/or QUEUE_CONNECTION, SESSION_DRIVER), or - | • Keep CACHE_STORE=redis and set VALKEY_FROM_REDIS=true to route the - | existing "redis" bindings through Valkey transparently. + | Valkey is a BSD-licensed, high performance key-value store that is fully + | wire-compatible with Redis. Each option falls back to its "REDIS_*" + | equivalent, so existing Redis applications may adopt Valkey without any + | additional configuration by setting the "VALKEY_FROM_REDIS" option. | */ 'valkey' => [ - // When true, the existing "redis" cache store / queue / session - // drivers (and Redis:: facade calls) transparently route through the - // Valkey (GLIDE) backend — keep CACHE_STORE=redis for a zero-config swap. 'from_redis' => env('VALKEY_FROM_REDIS', false), - // Client implementation used to talk to Valkey (GLIDE-based driver). 'client' => env('VALKEY_CLIENT', 'valkey_glide'), 'options' => [ - // Cluster mode marker passed to the connector ("redis" or ""). 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER', 'redis')), - // Key prefix applied to every command; defaults to the app slug. 'prefix' => env('VALKEY_PREFIX', env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-')), - // Whether to reuse persistent connections between requests. 'persistent' => env('VALKEY_PERSISTENT', env('REDIS_PERSISTENT', false)), + 'use_tls' => env('VALKEY_TLS', false), + 'read_from' => env('VALKEY_READ_FROM', 'primary'), + 'az_affinity' => env('VALKEY_AZ_AFFINITY'), ], 'default' => [ - // Full connection URL; overrides the discrete host/port keys below. 'url' => env('VALKEY_URL', env('REDIS_URL')), - // Hostname/IP of the Valkey primary node. 'host' => env('VALKEY_HOST', env('REDIS_HOST', '127.0.0.1')), - // ACL username (Valkey 6+); null uses the default user. 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), - // Auth password / ACL secret. 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), - // TCP port of the Valkey server. 'port' => env('VALKEY_PORT', env('REDIS_PORT', '6379')), - // Logical database index for general connection usage. 'database' => env('VALKEY_DB', env('REDIS_DB', '0')), - // Max automatic command retries before failing. 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES', 3)), - // Retry backoff strategy between attempts. 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter')), - // Base backoff delay in milliseconds. 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE', 100)), - // Maximum backoff delay cap in milliseconds. 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP', 1000)), ], 'cache' => [ - // Full connection URL; overrides the discrete host/port keys below. 'url' => env('VALKEY_URL', env('REDIS_URL')), - // Hostname/IP of the Valkey primary node. 'host' => env('VALKEY_HOST', env('REDIS_HOST', '127.0.0.1')), - // ACL username (Valkey 6+); null uses the default user. 'username' => env('VALKEY_USERNAME', env('REDIS_USERNAME')), - // Auth password / ACL secret. 'password' => env('VALKEY_PASSWORD', env('REDIS_PASSWORD')), - // TCP port of the Valkey server. 'port' => env('VALKEY_PORT', env('REDIS_PORT', '6379')), - // Dedicated logical database index for the cache store. 'database' => env('VALKEY_CACHE_DB', env('REDIS_CACHE_DB', '1')), - // Max automatic command retries before failing. 'max_retries' => env('VALKEY_MAX_RETRIES', env('REDIS_MAX_RETRIES', 3)), - // Retry backoff strategy between attempts. 'backoff_algorithm' => env('VALKEY_BACKOFF_ALGORITHM', env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter')), - // Base backoff delay in milliseconds. 'backoff_base' => env('VALKEY_BACKOFF_BASE', env('REDIS_BACKOFF_BASE', 100)), - // Maximum backoff delay cap in milliseconds. 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP', 1000)), ], - // Enable TLS/SSL for all connections in this group. - 'use_tls' => env('VALKEY_TLS', false), - // Read routing policy: primary | prefer_replica | az_affinity | any. - 'read_from' => env('VALKEY_READ_FROM', 'primary'), - // Availability-zone affinity for same-AZ replica reads. Takes effect - // when read_from is "az_affinity"; set the AZ your app runs in. - 'az_affinity' => [ - 'enabled' => env('VALKEY_AZ_AFFINITY', false), - 'az' => env('VALKEY_AZ'), - ], - // Per-request timeout in milliseconds. - 'request_timeout' => env('VALKEY_REQUEST_TIMEOUT', 250), - // Connection establishment timeout in milliseconds. - 'connection_timeout' => env('VALKEY_CONNECTION_TIMEOUT', 250), - // Optional client name reported to the server (CLIENT SETNAME). - 'client_name' => env('VALKEY_CLIENT_NAME'), - // Defer connecting until the first command is issued. - 'lazy_connect' => env('VALKEY_LAZY_CONNECT', false), - // Cap on concurrent in-flight requests per connection. - 'inflight_requests_limit' => env('VALKEY_INFLIGHT_LIMIT', 1000), - - /* - |---------------------------------------------------------------------- - | Valkey-Native Options (GLIDE) - |---------------------------------------------------------------------- - | - | The keys above are Redis-compatible and "just work" with existing - | REDIS_* environment variables. The options below expose GLIDE's - | Valkey-native capabilities — all are optional and default off/unset. - | Add any of these keys to a connection array to enable them: - | - | - | // AWS ElastiCache / MemoryDB IAM auth - | 'iam_config' => null, // Set to array to enable - | - | // Reconnect / backoff strategy - | 'reconnect_strategy' => [ - | 'num_of_retries' => env('VALKEY_RECONNECT_RETRIES', 3), - | 'factor' => env('VALKEY_RECONNECT_FACTOR', 2), - | 'exponent_base' => env('VALKEY_RECONNECT_EXP_BASE', 2), - | ], - | - | // Client-side caching (server-assisted invalidation) - | 'client_side_cache' => [ - | 'enabled' => env('VALKEY_CSC_ENABLED', false), - | 'max_size' => env('VALKEY_CSC_MAX_SIZE', 10000), - | ], - | - | // Native payload compression (experimental) - | 'compression' => [ - | 'enabled' => env('VALKEY_COMPRESSION', false), - | 'algorithm' => env('VALKEY_COMPRESSION_ALGO', 'lz4'), - | ], - | - */ - - 'clusters' => [ - - // 'default' => [ - // ['host' => '10.0.0.1', 'port' => 7000], - // ['host' => '10.0.0.2', 'port' => 7001], - // ['host' => '10.0.0.3', 'port' => 7002], - // ], - // 'options' => [ - // 'read_from' => 'prefer_replica', - // 'use_tls' => true, - // 'az_affinity' => ['enabled' => true, 'az' => 'us-east-1a'], - // ], - - ], - - 'otel' => [ - 'enabled' => env('VALKEY_OTEL_ENABLED', false), - 'endpoint' => env('VALKEY_OTEL_ENDPOINT'), - 'traces' => ['enabled' => true, 'sample_percentage' => env('VALKEY_OTEL_SAMPLE_PCT', 1)], - 'metrics' => ['enabled' => true], - 'flush_interval_ms' => env('VALKEY_OTEL_FLUSH_MS', 5000), - ], - - 'register_phpredis_aliases' => env('VALKEY_REGISTER_ALIASES', true), - ], ]; From c15392e362bce1f95488f0fb5eebadd18426da61 Mon Sep 17 00:00:00 2001 From: Roberto Luna-Rojas Date: Sat, 4 Jul 2026 22:05:56 -0400 Subject: [PATCH 5/5] docs(database): Restore optional Valkey options as commented reference The earlier simplification dropped the optional GLIDE capabilities entirely. Restore them as commented, disabled-by-default reference (timeouts, client_name, lazy_connect, inflight limit, phpredis aliases, IAM auth, reconnect strategy, client-side cache, compression, clusters, and OpenTelemetry) so the active config stays as concise as the redis block while still documenting what is available. Expand the section doc-block to list the Valkey-native options and their supported values, notably VALKEY_READ_FROM (primary, prefer_replica, az_affinity, any). Signed-off-by: Roberto Luna-Rojas --- config/database.php | 67 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/config/database.php b/config/database.php index 81cd07743a96..31b0515bf351 100644 --- a/config/database.php +++ b/config/database.php @@ -201,6 +201,16 @@ | equivalent, so existing Redis applications may adopt Valkey without any | additional configuration by setting the "VALKEY_FROM_REDIS" option. | + | The GLIDE client also exposes a handful of Valkey-native options: + | + | VALKEY_READ_FROM primary, prefer_replica, az_affinity, any + | VALKEY_TLS true to enable TLS/SSL for every connection + | VALKEY_AZ_AFFINITY availability zone used when read_from is "az_affinity" + | + | Further GLIDE capabilities (IAM auth, reconnect strategy, client-side + | caching, compression, clustering, and OpenTelemetry) may be enabled via + | the commented options shown below. + | */ 'valkey' => [ @@ -210,7 +220,7 @@ 'client' => env('VALKEY_CLIENT', 'valkey_glide'), 'options' => [ - 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER', 'redis')), + 'cluster' => env('VALKEY_CLUSTER', env('REDIS_CLUSTER', 'valkey')), 'prefix' => env('VALKEY_PREFIX', env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-')), 'persistent' => env('VALKEY_PERSISTENT', env('REDIS_PERSISTENT', false)), 'use_tls' => env('VALKEY_TLS', false), @@ -244,6 +254,61 @@ 'backoff_cap' => env('VALKEY_BACKOFF_CAP', env('REDIS_BACKOFF_CAP', 1000)), ], + // The options below expose additional GLIDE capabilities. They are + // optional and disabled by default — uncomment any you wish to use. + + // 'request_timeout' => env('VALKEY_REQUEST_TIMEOUT', 250), + // 'connection_timeout' => env('VALKEY_CONNECTION_TIMEOUT', 250), + // 'client_name' => env('VALKEY_CLIENT_NAME'), + // 'lazy_connect' => env('VALKEY_LAZY_CONNECT', false), + // 'inflight_requests_limit' => env('VALKEY_INFLIGHT_LIMIT', 1000), + // 'register_phpredis_aliases' => env('VALKEY_REGISTER_ALIASES', true), + + // AWS ElastiCache / MemoryDB IAM authentication. + // 'iam_config' => null, + + // Reconnect / backoff strategy. + // 'reconnect_strategy' => [ + // 'num_of_retries' => env('VALKEY_RECONNECT_RETRIES', 3), + // 'factor' => env('VALKEY_RECONNECT_FACTOR', 2), + // 'exponent_base' => env('VALKEY_RECONNECT_EXP_BASE', 2), + // ], + + // Client-side caching (server-assisted invalidation). + // 'client_side_cache' => [ + // 'enabled' => env('VALKEY_CSC_ENABLED', false), + // 'max_size' => env('VALKEY_CSC_MAX_SIZE', 10000), + // ], + + // Native payload compression (experimental). + // 'compression' => [ + // 'enabled' => env('VALKEY_COMPRESSION', false), + // 'algorithm' => env('VALKEY_COMPRESSION_ALGO', 'lz4'), + // ], + + // Cluster node definitions for multi-node deployments. + // 'clusters' => [ + // 'default' => [ + // ['host' => '10.0.0.1', 'port' => 7000], + // ['host' => '10.0.0.2', 'port' => 7001], + // ['host' => '10.0.0.3', 'port' => 7002], + // ], + // 'options' => [ + // 'read_from' => 'prefer_replica', + // 'use_tls' => true, + // 'az_affinity' => 'us-east-1a', + // ], + // ], + + // OpenTelemetry tracing and metrics export. + // 'otel' => [ + // 'enabled' => env('VALKEY_OTEL_ENABLED', false), + // 'endpoint' => env('VALKEY_OTEL_ENDPOINT'), + // 'traces' => ['enabled' => true, 'sample_percentage' => env('VALKEY_OTEL_SAMPLE_PCT', 1)], + // 'metrics' => ['enabled' => true], + // 'flush_interval_ms' => env('VALKEY_OTEL_FLUSH_MS', 5000), + // ], + ], ];