Redis (cache & sessions)
Since Maho 25.5 adds a completely new cache subsystem based on symfony/cache, Maho supports Redis for both cache and session storage out of the box, no 3rd party plugin needed.
Cache
If you want to enable it, and you've a Redis database available, simply head out to your local.xml file and configure the global/cache section this way:
<global>
<cache>
<lifetime>86400</lifetime> <!-- optional, default is 7200 -->
<backend>redis</backend> <!-- optional, default is file -->
<backend_options> <!-- optional for "file", required for "redis" -->
<dsn>redis://localhost/0</dsn> <!-- TCP connection, database 0 -->
</backend_options>
</cache>
</global>
The dsn element supports many possible options, check out of the full documentation at Symfony's website. For example, using a Unix socket (often faster than TCP on the same host):
Sessions
Redis can also be used for session storage, independently from the cache:
<global>
<session_save>redis</session_save>
<redis_session>
<dsn>redis:///var/run/redis/redis.sock/1</dsn> <!-- use a different database than the cache -->
<key_prefix>maho_session:</key_prefix> <!-- optional -->
</redis_session>
</global>
Sessions use the same DSN format as the cache (both TCP redis://host:port/db and Unix socket redis:///path/to/socket/db are supported). It's good practice to point sessions to a different database number than the cache.
Complete example with both cache and sessions
<global>
<session_save>redis</session_save>
<redis_session>
<dsn>redis:///var/run/redis/redis.sock/1</dsn>
<key_prefix>maho_session:</key_prefix>
</redis_session>
<cache>
<lifetime>86400</lifetime>
<backend>redis</backend>
<backend_options>
<dsn>redis:///var/run/redis/redis.sock/0</dsn>
</backend_options>
</cache>
</global>
Important: Redis maxmemory-policy requirement
Maho's cache backend uses Symfony's RedisTagAwareAdapter, which requires a maxmemory-policy of either noeviction or any volatile-* value (e.g. volatile-lfu, volatile-lru). The tag sets are stored without a TTL and must survive the cached items that have one, something the allkeys-* policies cannot guarantee.
Policies like allkeys-lfu or allkeys-lru cause the cache backend to silently fail to save any data, with no visible error.
Configure Redis accordingly in /etc/redis/redis.conf:
volatile-lfu provides the same LFU eviction behavior as allkeys-lfu, but only evicts keys that have a TTL set (cache data), preserving tag metadata keys that have no expiration. This requirement applies even when maxmemory is 0 (unlimited), because the adapter checks the reported policy regardless of whether eviction would actually happen. On managed Redis (AWS ElastiCache, Redis Cloud, etc.) change it from the provider's parameter group / dashboard.
You can also apply the change at runtime (set it in redis.conf too, or it's lost on restart):
Sessions are not affected by this restriction
Session storage uses Symfony's plain RedisAdapter (no cache tags), so the noeviction / volatile-* requirement does not apply to the session database. Since session keys always carry a TTL, a volatile-* policy is still the sensible choice if you share the same Redis instance.