Best practices for Valkey and Redis service configuration
Use these recommendations when configuring Redis or Valkey for Adobe Commerce application cache, session storage, and L2 cache for Adobe Commerce on Cloud deployments.
For Adobe Commerce on-premises cache configuration, see L2 cache configuration for performance optimization.
These recommendations cover the following:
- Select a supported cache service
- Enable replica connection
- Separate cache and session instances
- Configure cache compression
- Enable asynchronous freeing
- Enable multithreaded I/O
- Increase client timeouts and retries
- Configure L2 cache, including preload keys, stale cache, and Symfony L2 cache
- Review configuration examples
Select a supported cache service
Redis is not supported for cache configuration in Adobe Commerce 2.4.9 and in patch releases where system requirements specify Valkey instead. Always verify the exact Commerce version, patch level, and service version in the Cache backend options and storage reference and System requirements.
ece-tools package. If not, upgrade to the latest version. You can check the version installed in your local environment using the composer show magento/ece-tools CLI command.Enable replica connection
Enable the replica connection in the .magento.env.yaml file. This change allows Adobe Commerce to use an additional cache connection for reads while continuing to use the primary endpoint for writes. This configuration can reduce read load on the primary cache service and distribute read traffic more effectively.
ece-tools version. Before relying on this setting, confirm that a replica relationship exists for your service by running echo $MAGENTO_CLOUD_RELATIONSHIPS | base64 -d | json_pp and checking for a USE_SLAVE_CONNECTION entry. To confirm whether your topology provisions a replica endpoint, upgrade ece-tools and redeploy, or contact Adobe Commerce Support if no USE_SLAVE_CONNECTION entry is present.symfony_l2, replica connection support is delivered through an ece-tools and Cloud Patches update. No additional cache configuration is required beyond changing VALKEY_USE_SLAVE_CONNECTION: true. Update to the latest ece-tools version to receive the fix.For Valkey, use:
| code language-yaml |
|---|
|
For environment variable configuration details, see VALKEY_USE_SLAVE_CONNECTION in the Commerce on Cloud Infrastructure Guide.
For Redis, use:
| code language-yaml |
|---|
|
For environment variable configuration details, see REDIS_USE_SLAVE_CONNECTION in the Commerce on Cloud Infrastructure Guide.
Separate cache and session instances
Cache and session configuration are independent. SESSION_CONFIGURATION does not affect cache behavior, regardless of which cache backend or L2 cache implementation you use. Separating the cache from the sessions allows you to manage them independently. It reduces contention between cache and session traffic, prevents cache-related pressure from affecting sessions, and allows each Redis or Valkey instance to be sized and tuned for its own workload.
.magento/services.yaml and .magento.app.yaml files, as described in step 3 below.To provision a dedicated instance for sessions, follow the steps below:
-
Update the
.magento/services.yamlconfiguration file, replacing<version>with the service versions that you are using. See System requirements for supported service versions by release.code language-yaml mysql: type: mysql:<version> disk: 35000 valkey: type: valkey:<version> valkey-session: # This is for the new Valkey instance type: valkey:<version> search: type: elasticsearch:<version> disk: 5000 rabbitmq: type: rabbitmq:<version> disk: 2048 -
Update the
.magento.app.yamlconfiguration file.code language-yaml relationships: database: "mysql:mysql" valkey: "valkey:valkey" valkey-session: "valkey-session:valkey" # Relationship of the new Valkey instance search: "search:elasticsearch" rabbitmq: "rabbitmq:rabbitmq" -
Request a new Valkey instance dedicated to sessions on Production and Staging environments.
Submit an Adobe Commerce Support ticket. Include the updated
.magento/services.yamland.magento.app.yamlconfiguration files.This update does not cause any downtime, but it requires a deployment to activate the new service.
-
Verify that the new instance is running, and note the port number.
code language-shell echo $MAGENTO_CLOUD_RELATIONSHIPS | base64 -d | json_pp -
Add the port number to the
.magento.env.yamlconfiguration file.note important IMPORTANT Configure the Valkey session port only if ece-toolsis unable to automatically detect it from theMAGENTO_CLOUD_RELATIONSHIPSValkey session service definition.note NOTE Set disable_lockingto1for best performance. In rare cases where race conditions occur due to high concurrent session activity, set it to0to enable locking.code language-yaml SESSION_CONFIGURATION: _merge: true redis: # keep 'redis' even if you are using Valkey. timeout: 5 disable_locking: 1 bot_first_lifetime: 60 bot_lifetime: 7200 max_lifetime: 2592000 min_lifetime: 60 -
Remove sessions from the default database (
db 0) on the Valkey cache instance.code language-terminal valkey-cli -h 127.0.0.1 -p 6370 -n 0 FLUSHDB
-
Update the
.magento/services.yamlconfiguration file, replacing<version>with the service versions that you are using.code language-yaml mysql: type: mysql:<version> disk: 35000 redis: type: redis:<version> redis-session: # This is for the new Redis instance type: redis:<version> search: type: elasticsearch:<version> disk: 5000 rabbitmq: type: rabbitmq:<version> disk: 2048 -
Update the
.magento.app.yamlconfiguration file.code language-yaml relationships: database: "mysql:mysql" redis: "redis:redis" redis-session: "redis-session:redis" # Relationship of the new Redis instance search: "search:elasticsearch" rabbitmq: "rabbitmq:rabbitmq" -
Request a new Redis instance dedicated to sessions on Production and Staging environments.
Submit an Adobe Commerce Support ticket. Include the updated
.magento/services.yamland.magento.app.yamlconfiguration files.This update does not cause any downtime, but it requires a deployment to activate the new service.
-
Verify that the new instance is running, and note the port number.
code language-shell echo $MAGENTO_CLOUD_RELATIONSHIPS | base64 -d | json_pp -
Add the port number to the
.magento.env.yamlconfiguration file.note important IMPORTANT Configure the Redis session port only if ece-toolsis unable to automatically detect it from theMAGENTO_CLOUD_RELATIONSHIPSRedis session service definition.note NOTE Set disable_lockingto1for best performance. In rare cases where race conditions occur due to high concurrent session activity, set it to0to enable locking.code language-yaml SESSION_CONFIGURATION: _merge: true redis: timeout: 5 disable_locking: 1 bot_first_lifetime: 60 bot_lifetime: 7200 max_lifetime: 2592000 min_lifetime: 60 -
Remove sessions from the default database (
db 0) on the Redis cache instance.code language-terminal redis-cli -h 127.0.0.1 -p 6370 -n 0 FLUSHDB
Cache compression
If you use more than 6 GB of Redis or Valkey maxmemory, you can enable cache compression to reduce the space consumed by keys. Note that this setting trades client-side performance for memory savings. If you have spare CPU capacity, consider enabling it. See Use Redis for session storage or Use Valkey for session storage in the Configuration Guide.
stage:
deploy:
CACHE_CONFIGURATION:
_merge: true
frontend:
default:
backend_options:
compress_data: 4 # 0-9
compress_tags: 4 # 0-9
compress_threshold: 20480 # don't compress files smaller than this value
compression_lib: 'gzip' # snappy and lzf for performance, gzip for high compression (~69%)
Enable asynchronous freeing
To enable lazyfree on Adobe Commerce cloud infrastructure, submit an Adobe Commerce Support ticket requesting that the following Redis or Valkey configuration be applied to your environments:
lazyfree-lazy-eviction yes
lazyfree-lazy-expire yes
lazyfree-lazy-server-del yes
replica-lazy-flush yes
lazyfree-lazy-user-del yes
When lazyfree is enabled, Redis or Valkey offloads memory reclamation to background threads for evictions, expirations, server-initiated deletes, user deletes, and replica dataset flushes. This reduces main-thread blocking and can lower request latency.
lazyfree-lazy-user-del yes option makes the DEL command behave like UNLINK, which unlinks keys immediately and frees their memory asynchronously.Enable multithreaded I/O
To enable Redis I/O threading on Adobe Commerce cloud infrastructure, submit an Adobe Commerce Support ticket requesting the I/O threading configuration below. This configuration can improve throughput by offloading socket reads, writes, and command parsing from the main thread, at the cost of higher CPU usage. Validate under load and monitor your hosts.
For Redis:
| code language-text |
|---|
|
For Valkey:
| code language-text |
|---|
|
io-threads or disable reads in I/O threads.Increase client timeouts and retries
Increase the Redis or Valkey cache client’s tolerance to short periods of saturation by adjusting the backend options in .magento.env.yaml.
stage:
deploy:
CACHE_CONFIGURATION:
_merge: true
frontend:
default:
backend_options:
connect_retries: 3 # Number of connection retries
remote_backend_options:
read_timeout: 10 # Timeout
These settings can reduce intermittent connection and read-timeout errors during short spikes by retrying connection setup and allowing more time for replies from Redis or Valkey.
Configure L2 cache
Configure the L2 cache by setting the VALKEY_BACKEND or REDIS_BACKEND deployment variable in the .magento.env.yaml configuration file.
There are two L2 cache implementations available for Adobe Commerce on cloud infrastructure.
- Legacy implementation uses
RemoteSynchronizedCachewithCm_Cache_Backend_Filefor local storage - Modern implementation uses
symfony_l2with PSR-6 compliance and enhanced performance. The modern implementation supports Valkey only.
(if Valkey is supported)
VALKEY_BACKEND: '\Magento\Framework\Cache\Backend\RemoteSynchronizedCache'VALKEY_BACKEND: 'symfony_l2'On Commerce 2.4.8 and earlier versions that support Valkey, use this configuration:
| code language-yaml |
|---|
|
On Commerce 2.4.9 and later, use the following configuration with the Symfony L2 implementation:
| code language-yaml |
|---|
|
On version 2.4.8 and earlier Commerce versions that support Redis, use:
| code language-yaml |
|---|
|
For environment configuration details, see REDIS_BACKEND in the Commerce on Cloud Infrastructure Guide.
Migrate to Valkey with Symfony L2 cache
If you are migrating an existing Adobe Commerce on Cloud project from RemoteSynchronizedCache (Redis or Valkey) to symfony_l2, review the following before updating .magento.env.yaml.
-
Changing the deploy variable is sufficient to enable
symfony_l2. SettingVALKEY_BACKEND: symfony_l2alone builds the full L2 cache configuration automatically. You do not need to manually recreate thebackend_optionsstructure your previousRemoteSynchronizedCacheconfiguration used. See Configure Symfony L2 cache. -
Remove
preload_keysfrom your existing configuration. If yourRemoteSynchronizedCacheconfiguration includespreload_keysunderCACHE_CONFIGURATION, remove it as part of the migration. See Preload keys for details. -
Stale cache behavior changes automatically. Under
symfony_l2,ece-toolsautomatically enables stale cache for common cache types (such aslayout,block_html,full_page, andtranslate) without requiring the manual frontend configuration thatRemoteSynchronizedCacheneeded. If you previously configured stale cache manually and want to retain your exact prior behavior, review Enable stale cache before migrating. -
Compression requires an explicit flag. If you customize
symfony_l2compression throughCACHE_CONFIGURATION, settingcompression_libalone does not enable compression —compress_datamust also be set. See Cache compression. -
Redis is not a supported remote backend for
symfony_l2. Migrate to Valkey as part of this change. See Set up Valkey service. -
Session configuration is unaffected by this migration.
SESSION_CONFIGURATIONis independent of the cache backend and does not need to change when moving tosymfony_l2. See Separate cache and session instances.
symfony_l2 manually in app/etc/env.php. Configure it through .magento.env.yaml so ece-tools applies and maintains the setting during deployment. See Configure Symfony L2 cache.Preload keys
Preload keys can be applied to a symfony_l2 configuration if you use the correct placement (under backend_options or remote_backend_options). However, Adobe does not recommend using preload keys with symfony_l2. The symfony_l2 preload implementation fetches keys one at a time, so it does not reduce round trips the way it does for RemoteSynchronizedCache, and it can increase load on Valkey without a performance benefit.
The preload feature lets you provide a list of frequently used keys that Magento fetches in a single pipeline on first access during a request. Magento then keeps the fetched values in PHP memory for the rest of that request, which reduces repeated round trips to Redis or Valkey and can improve request bootstrap performance for those keys.
You can identify frequently used keys by monitoring active commands on Redis or Valkey:
The preload keys are configured in the .magento.env.yaml configuration file. This example shows the configuration for Adobe Commerce 2.4.8 and earlier versions that support RemoteSynchronizedCache.
stage:
deploy:
REDIS_BACKEND: '\Magento\Framework\Cache\Backend\RemoteSynchronizedCache'
CACHE_CONFIGURATION:
_merge: true
frontend:
default:
id_prefix: '061_' # Prefix for keys to be preloaded, it can be any random string
backend_options:
preload_keys: # List the keys to be preloaded
- '061_EAV_ENTITY_TYPES:hash' # The key name must start with the id_prefix set above
- '061_GLOBAL_PLUGIN_LIST:hash'
- '061_DB_IS_UP_TO_DATE:hash'
- '061_SYSTEM_DEFAULT:hash'
To list the keys, run the following command:
redis-cli -p 6370 -n 1 MONITOR > /tmp/list.keys
After 10 seconds, press Ctrl+C. Then run the following command:
cat /tmp/list.keys | grep "HGET" | awk '{print $5}' | sort | uniq -c | sort -nr | head -n 50
This log lists the keys you can preload. To see the content of a key, run the following command:
redis-cli -p 6370 -n 1 hgetall "<key_name>"
Enable stale cache
Stale cache is an L2 cache feature that lets Adobe Commerce serve an existing local cache value from /dev/shm while another request is already regenerating the same entry. This prevents concurrent requests from waiting. This reduces cache stampedes and lock contention during regeneration of expensive cache entries.
For Adobe Commerce 2.4.9 and later, set VALKEY_BACKEND: symfony_l2 in the .magento.env.yaml file:
stage:
deploy:
VALKEY_BACKEND: symfony_l2
ece-tools automatically generates both a default frontend and a stale_cache_enabled frontend, and maps the following cache types to the stale-enabled frontend: layout, block_html, reflection, config_integration, config_integration_api, full_page, and translate. No manual use_stale_cache or frontend configuration is required for these types. This automatic mapping is itself an example of selective stale cache enablement. Only specific cache types use the stale-enabled frontend, not all of them. To customize which types map to stale_cache_enabled, or to add types beyond the defaults, see Customize the Symfony L2 cache configuration.
full_page cache type is not relevant to Adobe Commerce on Cloud infrastructure projects because they use Fastly for full-page caching. The manual configuration examples in this section omit full_page for that reason, even though ece-tools includes it in the default symfony_l2 mapping.The following legacy configuration applies to Adobe Commerce 2.4.8 and earlier, which use RemoteSynchronizedCache and require manual stale cache and frontend configuration. The same selective-over-global recommendation applies here.
How the legacy RemoteSynchronizedCache backend works
With RemoteSynchronizedCache, Magento maintains two copies of each cache entry: a local copy in /dev/shm and a remote copy in Redis or Valkey. When the remote copy is unavailable and a regeneration lock already exists for that key, concurrent requests can receive the previous local value instead of waiting until the fresh value is written.
To enable stale cache for 2.4.8 and earlier versions, configure it in the .magento.env.yaml file.
stage:
deploy:
REDIS_BACKEND: '\Magento\Framework\Cache\Backend\RemoteSynchronizedCache'
CACHE_CONFIGURATION:
_merge: true
frontend:
default:
backend_options:
use_stale_cache: true
default cache frontend, which applies stale-cache behavior to all cache entries that use that frontend. Magento core cache types work as expected with this setting. However, if your project includes custom code or extensions that write to the cache through the generic \Magento\Framework\App\Cache API (for example $this->cache->save()) without a dedicated cache frontend, those entries can also serve stale values during regeneration.default frontend and enable it only for selected cache types, as shown below.Enable stale cache per cache type individually (legacy)
You can enable stale cache only for selected cache types by defining a dedicated cache frontend in .magento.env.yaml and mapping the selected cache types to it. This manual approach applies to the legacy RemoteSynchronizedCache backend; symfony_l2 performs this mapping automatically, as described above.
To work correctly, the custom frontend must be defined as a complete frontend under CACHE_CONFIGURATION.frontend. Defining only use_stale_cache: true for a new frontend name is not enough.
Example configurations
For Redis on versions 2.4.8 and earlier, the following configuration enables stale cache for the layout, reflection, config_integration, config_integration_api, and translate cache types, while leaving others using the default frontend with stale cache disabled:
stage:
deploy:
REDIS_BACKEND: '\Magento\Framework\Cache\Backend\RemoteSynchronizedCache'
CACHE_CONFIGURATION:
_merge: true
frontend:
default: # In this frontend, we keep stale cache set to false.
id_prefix: '001_'
backend_options:
use_stale_cache: false
# Now, create a new frontend called 'stale_cache_enabled'.
# It must contain the same backend connection settings as the frontend 'default':
stale_cache_enabled:
id_prefix: '001_'
backend: '\Magento\Framework\Cache\Backend\RemoteSynchronizedCache'
backend_options:
remote_backend: '\Magento\Framework\Cache\Backend\Redis'
remote_backend_options:
server: localhost
port: 6370 # Use the same port used by the frontend 'default' in env.php
database: 1
load_from_slave:
server: localhost
port: 26370 # Use the same port used by the frontend 'default' in env.php
retry_reads_on_master: 1
read_timeout: 10
local_backend: 'Cm_Cache_Backend_File'
local_backend_options:
cache_dir: /dev/shm/
use_stale_cache: true # stale cache here is enabled
# Now select which cache types you want to enable (stale_cache_enabled), or disable (default)
type:
default:
frontend: default
layout:
frontend: stale_cache_enabled
reflection:
frontend: stale_cache_enabled
config_integration:
frontend: stale_cache_enabled
config_integration_api:
frontend: stale_cache_enabled
translate:
frontend: stale_cache_enabled
# add other cache types as needed...
stale_cache_enabled so that the new frontend maintains the same behavior.Configure Symfony L2 cache
Adobe Commerce 2.4.9 and later support the symfony_l2 cache backend. The symfony_l2 backend is the cache implementation that Adobe Commerce uses to manage L1 and L2 cache behavior. It does not replace Redis or Valkey as the remote cache service.
symfony_l2 through the .magento.env.yaml deployment variable so ece-tools applies and maintains the setting during deployment. Do not configure symfony_l2 manually in app/etc/env.php, because deployment can overwrite manual env.php changes. If ece-tools does not apply symfony_l2, Commerce can fall back to file-based cache, which can increase disk I/O, add file system replication overhead on multi-node environments, and degrade performance.To use symfony_l2 cache for Adobe Commerce 2.4.9, complete these steps:
-
Ensure that the cloud project is using
ece-toolspackage v2002.2.12 or later. -
Set the deployment variable in the
.magento.env.yamlfile:VALKEY_BACKEND=symfony_l2.code language-yaml stage: deploy: VALKEY_BACKEND: symfony_l2
Setting the VALKEY_BACKEND deployment variable to symfony_l2 automatically builds the full L2 cache configuration from your Valkey service connection details, including default and stale_cache_enabled frontends, with common cache types already mapped. Defining CACHE_CONFIGURATION is optional and needed only if you want to customize specific backend options.
cleanup_percentage). This reduces disk I/O and backend load while improving cache consistency. See Enhanced Symfony L2 cache performance and reliability in the Adobe Commerce Configuration Guide.ece-tools) and is applied automatically during deployment when you update to the latest ece-tools version. Update to the latest version of ece-tools to receive the patch.Customize the Symfony L2 cache configuration
ece-tools automatically derives the Valkey connection details (server, port, database, serializer, compression_lib, persistent_id) for the default and stale_cache_enabled frontends. To customize other backend options—such as the local cache directory—define CACHE_CONFIGURATION with _merge: true alongside VALKEY_BACKEND: symfony_l2. Values you define here override the corresponding auto-generated defaults; any options you omit continue to use the values that ece-tools derives automatically.
stage:
deploy:
VALKEY_BACKEND: symfony_l2
CACHE_CONFIGURATION:
_merge: true
frontend:
default:
backend_options:
remote_backend: valkey
local_backend: file
local_backend_options:
cache_dir: /dev/shm/magento_l1
stale_cache_enabled:
backend: symfony_l2
backend_options:
remote_backend: valkey
local_backend: file
local_backend_options:
cache_dir: /dev/shm/magento_l1_stale
use_stale_cache: true
CACHE_CONFIGURATION for symfony_l2, only override server or port if you are intentionally pointing to a cache endpoint other than your project’s Valkey service. The ece-tools package derives these values automatically from your Valkey service relationship.server, its value must be localhost when connecting to the project’s Valkey service. Providing an incorrect server or port value causes deployment to fail with a cache connection error.L2 cache memory sizing for Adobe Commerce Cloud
L2 cache uses a temporary file system (/dev/shm) as its storage mechanism. Unlike specialized key-value stores, tmpfs has no key eviction policy, so memory usage can grow unbounded. To prevent exhaustion, Adobe Commerce automatically clears the L2 storage when usage reaches a configurable threshold (95% by default). You can control memory consumption by requesting a larger /dev/shm mount or by lowering the cleanup threshold.
Adjust the maximum L2 cache memory usage based on your project requirements. Use one of the following methods:
- To adjust the
/dev/shmmount size, create a support ticket. For this scenario, Adobe recommends setting the/dev/shmmount size to 15 GB. - Adjust the
cleanup_percentageproperty at the application level to cap storage usage and free memory available for other services.
You can adjust the configuration in the deployment configuration under the cache configuration groupcache/frontend/default/backend_options/cleanup_percentage.
cleanup_percentage configurable option was introduced in Adobe Commerce 2.4.4.The following examples show the configuration code in the .magento.env.yaml file:
For Commerce 2.4.9 and later, use the following configuration to set the cleanup threshold to 90%:
| code language-yaml |
|---|
|
For Commerce 2.4.8 and earlier, use the following configuration to set the cleanup threshold to 90%:
| code language-yaml |
|---|
|
Cache requirements vary based on your project configuration and custom third-party code. Size L2 cache memory so that the cache can operate without frequent threshold hits.
Ideally, L2 cache memory usage stabilizes below the threshold to avoid frequent storage clearing.
You can check L2 cache storage memory usage on each node of the cluster by running the following CLI command and reviewing the /dev/shm line.
df -h /dev/shm
Usage varies across nodes, but converges to a similar value.
Configuration examples
Use the following examples as a starting point for your Redis or Valkey service configurations.
Apply all best practice recommendations
For VALKEY_BACKEND: symfony_l2, let ece-tools generate the default and stale_cache_enabled frontends and their cache-type mappings. Do not set use_stale_cache on the broad default frontend. The CACHE_CONFIGURATION block below contains only explicit backend-option overrides.
| code language-yaml |
|---|
|
Use the following configuration for Redis on Adobe Commerce 2.4.8 and earlier:
| code language-yaml |
|---|
|
Separate stale cache by cache type
| code language-yaml |
|---|
|
| code language-yaml |
|---|
|