Are you looking for an effective optimization technique that improves your Magento 2 site's performance and responsiveness? Do you want to develop your store with a faster back-end cache?

You're in the right place. In this article, we will go through redis, how to setup redis with Magento 2 and some tips to optimize your redis Magento 2 experience.

1. What is Redis?

Redis is an in-memory database (a database that keeps the dataset in RAM) which periodically stores data back to disks. This makes Redis ideal as a cache system: the data is structured, its latency is lower and throughput is higher than data stored in disks, while still offers data persistent (compared to Memcache which doesn’t save data to disk by default).

2. How and when to use Redis with Magento 2

Magento 2 supports Redis as storage for the following data:

  • Backend cache
  • Full-page cache
  • Sessions

instead of default setting which store to files. Compared to files cache, Redis brings a much lower TTFB (time to first byte) value and higher concurrent requests.

As Redis operates on memory, ensure your server has enough RAM to spare for Redis cache. The more data managed by Redis, the higher memory consumption. High server availability is also a must - if the connection between Redis and file server is interrupted while saving from memory to disk, this data is considered lost.

3. Setup Redis in Magento 2

Install Redis 

Redis installation is straightforward on Unix-based systems, i.e. on Ubuntu (Debian):

sudo apt-get install redis

On CentOS

sudo yum install epel-release
sudo yum install redis -y

Start Redis on system boot:

sudo systemctl enable redis

Activate Redis

Before you proceed, backup your Magento environment parameters at [site root]/app/etc/env.php. Magento 2 doesn’t offer a clean way to return cache settings to ‘files’ using CLI, so you can use the backup to revert configuration if needed.

Cache system settings are stored under [site root]/app/etc/env.php. They can be changed by editing env.php directly, or by command line configuration.

a. Edit env.php

Default cache

Create the array cache => frontend => default[] as follows:

'cache' => [
        'frontend' => [
            'default' => [
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'database' => '0',
                    'port' => '6379',
			    'password' => '',
                    'compress_data' => '1',
                ]
            ]
        ]
    ],
  • backend: set config area
  • backend_options:  set options for backend cache
  • server: set address of redis database. 127.0.0.1 is used if redis is installed on the same environment
  • database: set database number used to store this cache
  • port: redis port. 6379 is default port of Redis
  • password: set password if Redis requires authentication
  • compress_data: set 1 to compress data (saves RAM, but slightly slower). If set to 1, Redis will choose compress algorithm automatically, or it can be specified via compression_lib parameter 
Page cache

Page cache uses the same cache => frontend array as default cache, or you can create this array (cache => frontend => page_cache) if you only use page cache:

'cache' => [
        'frontend' => [
            'page_cache' => [
            	'backend' => 'Cm_Cache_Backend_Redis',
            	'backend_options' => [
                	'server' => '127.0.0.1',
                	'database' => '1',
                	'port' => '0',
                	'password' => '',
                	'compress_data' => '0',
            	]
        	]
        ]
    ],

The parameters are similar between default and page_cachem only 'database' parameters must be different. 

Session save

Session save is configured in a different array session => save. By default, 'save' has value 'files'. To use Redis, you need to change the value to 'redis' and create subarray 'redis' containing Redis params. Session array will look like this:

'session' => [
        'save' => 'redis',
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '6379',
            'timeout' => '2.5',
            'database' => '2',
            'compression_threshold' => '2048',
            'compression_library' => 'gzip',
            'log_level' => '1',
            'max_concurrency' => '6',
            'break_after_frontend' => '5',
            'break_after_adminhtml' => '30',
            'first_lifetime' => '600',
            'bot_first_lifetime' => '60',
            'bot_lifetime' => '7200',
            'disable_locking' => '0',
            'min_lifetime' => '60',
            'max_lifetime' => '2592000',
            'sentinel_master' => '',
            'sentinel_servers' => '',
            'sentinel_connect_retries' => '5',
            'sentinel_verify_master' => '0'
        ]
    ],

Several parameters are exclusive to session save:

  • timeout: connection timeout (seconds)
  • compression_threshold: when a session's data size exceeds the compression threshold (in KB) the session data will be compressed
  • compression_library: select compression library, supports 'gzip', 'lzf', 'lz4', and 'snappy'
  • log_level: from least to most verbose:
    • 0 (emergency: only the most severe errors)
    • 1 (alert: immediate action required)
    • 2 (critical: application component unavailable)
    • 3 (error: runtime errors, not critical but must be monitored)
    • 4 (warning: additional information, recommended)
    • 5 (notice: normal but significant condition)
    • 6 (info: informational messages)
    • 7 (debug: the most information for development or testing only)
  • max_concurrency: maximum number of processes that can wait for a lock on one session. The recommended number is 10% the number of PHP processes or more.
  • break_after_frontend: Number of seconds to wait before trying to break the lock for frontend sessions
  • break_after_adminhtml: Number of seconds to wait before trying to break the lock for backend sessions
  • first_lifetime: Lifetime of session for non-bots on the first write. 0 to disable
  • bot_first_lifetime: Lifetime, in seconds, of session for bots on the first write, or use 0 to disable
  • bot_lifetime: Lifetime, in seconds, of session for bots on subsequent writes, or use 0 to disable
  • disable_locking: Disable session locking entirely
  • min_lifetime: Minimum session lifetime, in seconds
  • max_lifetime: Maximum session lifetime, in seconds

b. Command line configuration

Redis settings can be changed from Magento command line configuration. For example, from site root run the following command to activate redis:

php bin/magento setup:config:set --[cache type]=redis

Replace [cache type] with either cache-backend, page-cache or session-save to use Redis for the respective data.

To change any specific Redis parameter, use the following format

php bin/magento setup:config:set --[cache type]-redis-[parameter name]=[parameter value]

For example, to activate Redis for sessions save on the same server as Magento installation, and use database 2, run the following command:

php bin/magento setup:config:set  --session-save=redis --session-save-redis-host=127.0.0.1 --session-save-redis-db=2

Tip: Magento CLI supports shortcuts, so setup:config:set can be replaced with s:c:s

Caution: if Redis is used with multiple types, the database used for cache storage must be different between each type. This setting modifiable with parameter --[cache type]-redis-db.

A Magento 2 installation with Redis enabled for all 3 cache types would have the env.php file looking like this:

<?php
return [
   ...
    'session' => [
        'save' => 'redis',
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '0',
            'password' => '',
            'timeout' => '2.5',
            'persistent_identifier' => '',
            'database' => '2',
            'compression_threshold' => '2048',
            'compression_library' => 'gzip',
            'log_level' => '1',
            'max_concurrency' => '6',
            'break_after_frontend' => '5',
            'break_after_adminhtml' => '30',
            'first_lifetime' => '600',
            'bot_first_lifetime' => '60',
            'bot_lifetime' => '7200',
            'disable_locking' => '0',
            'min_lifetime' => '60',
            'max_lifetime' => '2592000',
            'sentinel_master' => '',
            'sentinel_servers' => '',
            'sentinel_connect_retries' => '5',
            'sentinel_verify_master' => '0'
        ]
    ],
    'cache' => [
        'frontend' => [
            'default' => [
                'id_prefix' => '8f5_',
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'database' => '0',
                    'port' => '0',
                    'password' => '',
                    'compress_data' => '1',
                    'compression_lib' => ''
                ]
            ],
            'page_cache' => [
                'id_prefix' => '8f5_',
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'database' => '1',
                    'port' => '0',
                    'password' => '',
                    'compress_data' => '0',
                    'compression_lib' => ''
                ]
            ]
        ]
    ],
  ...
];

Tip: default parameter values are stored under [site_root]/setup/src/Magento/Setup/Model/ConfigOptionsList/ for each type.

Verify Redis is running using the command redis-cli monitor then open a Magento page.

4. Performance Tuning

a. Limit memory usage

By default Redis has no memory limit, so it can consume as much memory as your system has available. This can become an issue if your server must spare RAM for Nginx, MySQL or other services. To set memory limit for Redis, open its configuration file ( /etc/redis/redis.conf on Ubuntu, or run whereis redis.conf if it’s not there ) and add this line:

maxmemory = [value];

Replace [value] with storage size in bytes. For example, 4096M will set a limit to 4GB. Memory limit should be equal or greater than cache size using file-based cache system. 2048M is often enough for sites with a few thousand products. Then use the command sudo systemctl restart redis to restart Redis service.

b. Use UNIX socket

If your web server and Redis are installed on the same machine, Magento can be configured to connect with Redis using UNIX socket, skipping TCP/IP protocol. To setup UNIX socket:

  • Add web server user to redis group i.e. sudo usermod -g www-data redis (replace www-data with your web server user)
  • Edit permission: Open redis.conf file and find the line with unixsocketperm, uncomment this line and change the permission value to 775. Save this file and restart Redis. 
  • Change Redis port: from Magento root, set port to 0 i.e. php bin/magento setup:config:set --session-save-redis-port=0

Direct UNIX socket connection is several times faster than going through TCP/IP. However, each request is already fast with TCP/IP (calculated in microseconds) so performance gain will not be visible until the number of requests per second is in thousands.

While there are other ways to get the best Redis performance, be aware that requests are still handled by your web server first (Nginx/Apache) so eventually Redis tuning will have no effect and you need to optimize web server to increase performance.

5. Summary

We’ve learned about Redis, how to use Redis in Magento 2 and a few tips to get the best performance out of your server with a better cache system, ultimately improving user experience on your shop. However Redis is only a piece in Magento 2 performance optimization, and we wish to introduce our readers to other optimization aspects in the future. Stay tuned!