Session management is one of those quiet performance killers that rarely gets attention until your store starts grinding under load. By default, Magento 2 stores sessions on the filesystem — a setup that works fine for a single-server development environment but falls apart fast in production. In this guide, we'll break down every viable session storage option, benchmark the trade-offs, and show you exactly how to configure Redis sessions the right way.
Why Session Storage Matters
Every visitor to your Magento store — logged-in or guest — gets a session. That session tracks their cart, wishlist, recently viewed products, and authentication state. On a busy store handling thousands of concurrent visitors, the overhead of reading and writing session data adds up fast.
The three main options are:
-
Filesystem sessions — the default, stored in
var/session/ -
Database sessions — stored in the
sessiontable in MySQL - Redis sessions — stored in memory via a dedicated Redis instance
Let's go through each in detail.
Filesystem Sessions
This is what you get out of the box. Magento writes a file per session to var/session/ using PHP's built-in file session handler.
Pros:
- Zero configuration
- Works immediately with no dependencies
- Easy to inspect for debugging
Cons:
- Does not scale to multiple web nodes (sessions are local to one server)
- File system I/O becomes a bottleneck under load
- No built-in expiration management — old session files accumulate and must be cleaned with cron
- Prone to race conditions under concurrent requests from the same session
On a single-server setup with moderate traffic (under ~100 concurrent users), filesystem sessions are acceptable. Beyond that, you're leaving performance on the table.
Database Sessions
Magento 2 supports storing sessions in the MySQL session table by setting the session save handler to db.
// app/etc/env.php
'session' => [
'save' => 'db',
],
Pros:
- Works across multiple web nodes
- Data is persistent across server restarts
- Session locking is handled correctly
Cons:
- Adds load to your MySQL server — often the most constrained resource
- Table grows without bound; requires aggressive cleanup
- Much slower than Redis for read/write operations (disk I/O vs memory)
- Locking overhead on high-concurrency stores
Database sessions are a step up from filesystem if you need multi-server support but can't run Redis. In practice, they're rarely the right long-term choice because they shift bottleneck load onto MySQL.
Redis Sessions — The Right Choice for Production
Redis is an in-memory data store, and it's the recommended session backend for any Magento 2 production environment. Magento ships with a built-in Redis session handler (Cm_RedisSession) from Magento 2.0.
Why Redis Wins
- Speed: Memory operations are orders of magnitude faster than disk or database I/O
- Automatic expiry: TTL-based expiration means no manual session cleanup
- Multi-node safe: All web servers share the same session store
- Concurrency handling: Built-in advisory locking prevents session corruption
- Monitoring: Redis CLI and tools like RedisInsight give full visibility into session data
Benchmark Context
On a typical Magento 2 store under load test (500 concurrent users, mixed cart/browse traffic):
| Backend | Avg. session read (ms) | Avg. session write (ms) | Server CPU impact |
|---|---|---|---|
| Filesystem | 8–15 | 12–20 | Low (disk I/O) |
| MySQL DB | 15–40 | 20–50 | High (query load) |
| Redis | 0.3–1 | 0.5–1.5 | Minimal |
These numbers vary by hardware, but the pattern is consistent: Redis session I/O is 10–50x faster than alternatives.
Configuring Redis Sessions in Magento 2
Prerequisites
- Redis installed and running (typically on port 6379)
- A separate Redis instance or database number for sessions vs. full page cache (important — see below)
Basic Configuration
Edit app/etc/env.php:
'session' => [
'save' => 'redis',
'redis' => [
'host' => '127.0.0.1',
'port' => '6379',
'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',
],
],
Key Parameters Explained
database — Use a different number (0, 1, 2...) than your default cache and full page cache Redis instances. Mixing them makes TTL and memory management a nightmare.
max_concurrency — Maximum number of processes that can wait for a session lock at once. The default of 6 is fine for most stores. Lower it on smaller servers to avoid Redis connection exhaustion.
break_after_frontend — Seconds to wait before breaking a session lock on the frontend. A value of 5 is aggressive but prevents hung requests from blocking the cart.
disable_locking — Leave this at 0. Disabling session locking speeds things up but causes data corruption on concurrent AJAX requests (e.g., add-to-cart + minicart update firing simultaneously).
compression_threshold — Session data over this size in bytes gets compressed. Reduces Redis memory usage for stores with large cart data or extensive customer session payloads.
bot_first_lifetime / bot_lifetime — Short TTLs for detected bots. This alone can dramatically reduce Redis memory usage on high-traffic stores where crawlers represent 20–40% of sessions.
Separating Sessions from Cache in Redis
A common mistake is pointing both cache and session at the same Redis instance with the same database number. This causes:
- Sessions and cached HTML blocks competing for memory
- When Redis hits
maxmemory, eviction policies may delete session data - Harder to tune TTLs independently
Recommended setup:
Redis DB 0 → Default cache (blocks, collections, config)
Redis DB 1 → Full Page Cache
Redis DB 2 → Sessions
Or use separate Redis ports/instances if your server has the memory to support it. For session storage, configure maxmemory-policy noeviction — you never want Redis silently dropping sessions because it ran out of memory. Size your Redis instance accordingly.
Redis Sentinel for High Availability
If your store needs zero-downtime session persistence, Redis Sentinel provides automatic failover. Magento 2 supports Sentinel natively through the same env.php configuration:
'sentinel_master' => 'mymaster',
'sentinel_servers' => '192.168.1.10:26379,192.168.1.11:26379,192.168.1.12:26379',
For most Magento stores, a single Redis instance with persistence (appendonly yes in redis.conf) is sufficient. Sentinel adds operational complexity that's only worth it at significant scale.
Session Lifetime Tuning
Session lifetime directly affects how long customers stay "logged in" and how much memory Redis consumes.
'max_lifetime' => '2592000', // 30 days — good for B2C
'first_lifetime' => '600', // 10 min for new/guest sessions
For B2B Magento stores with account-heavy workflows, longer lifetimes (90 days) reduce friction. For high-traffic B2C stores, shorter guest session lifetimes aggressively keep Redis memory usage down.
Run this command to check your current session count and memory usage:
redis-cli -n 2 info keyspace
redis-cli -n 2 dbsize
redis-cli info memory | grep used_memory_human
Flushing Sessions Safely
Never run redis-cli flushall in production — it wipes all Redis data including cache. To flush only sessions:
redis-cli -n 2 flushdb
To expire sessions for a specific customer (useful for security incidents), find and delete their session key:
redis-cli -n 2 keys "sess_*" | head -20
redis-cli -n 2 del sess_<session_id>
Verifying Your Configuration
After updating env.php, flush config and verify Redis is receiving session writes:
php bin/magento cache:flush config
redis-cli -n 2 monitor
Open your store in a browser and watch redis-cli monitor — you should see SET sess_* and GET sess_* commands flowing in.
Summary
| Filesystem | MySQL DB | Redis | |
|---|---|---|---|
| Speed | Medium | Slow | Fast |
| Multi-server | No | Yes | Yes |
| Auto-expiry | No | No | Yes |
| Memory safe | Yes | Yes | Needs tuning |
| Recommended | Dev only | Fallback | Production |
If you're running Magento 2 in production and haven't switched to Redis sessions yet, it's the single highest-impact configuration change you can make with the least risk. It's well-supported, well-documented, and the performance difference under real traffic is immediately measurable.
Start with a separate Redis database number, configure sane TTLs for bots and guests, and make sure maxmemory-policy is set to noeviction for the session database. Your checkout conversion rate (and your ops team) will thank you.
Top comments (0)