Successful migration: four PHP-FPM nodes behind a load balancer, sessions in Redis, deploys without mass logout. Redis network outage Tuesday 11 a.m.: 100% of users sent to login, carts cleared, support tickets multiplied by two hundred. Monitoring alerted PHP CPU — not Redis memory or refused connections.
This scenario illustrates the classic switch: Redis for sessions solves horizontal scale, but creates a critical dependency if treated as "disposable cache." Session is not recalculable HTML — it is in-progress user state: cart, MFA step, multi-page wizard.
Many teams discover the problem on first Redis outage day, not migration day. Before adding Redis, the question is not only "how to configure PHP?" but "what happens if Redis disappears for five minutes — and who gets alerted?"
Healthy architecture
| Component | Recommendation |
|---|---|
| Instance | Dedicated Redis sessions or separate DB 1 from cache |
| Persistence | AOF for recovery; sessions have TTL anyway |
| HA | Sentinel (3 nodes) or Redis Cluster if high load |
| Network | Private network, not Redis on public Internet |
| PHP | session.save_handler=redis, session.save_path=tcp://... |
Illustrative PHP config:
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?database=1&timeout=2&prefix=sess:"
session.gc_maxlifetime = 3600
Short timeout on Redis connection — fail fast better than blocking PHP-FPM 30 seconds.
Redis cache vs Redis sessions: do not mix
| Use | TTL | Eviction |
|---|---|---|
| App cache | Variable | allkeys-lru OK |
| Sessions | Sliding user activity | volatile-lru or noeviction |
Accidental FLUSHDB on shared cache = global logout. Separate instances or at least DB index.
Fallback: hope vs plan
Realistic options:
- HA Redis — primary pattern.
- Files fallback if Redis down — breaks load balancing without sticky; OK short emergency.
- Graceful degradation — maintenance login page if Redis health check fails.
Do not promise transparent "files backup" on four nodes without sticky.
Monitoring
Watch connected_clients, used_memory, rejected_connections. Measure latency with redis-cli --latency. Alert if master down (Sentinel). Correlate login 5xx spikes with Redis state.
Hosting: managed Redis (OVH, Scaleway) or dedicated VPS container — not Redis on same VM as PHP without strict memory limits. See also Redis or Memcached and Connection pooling.
The peak: Redis session is not cache — it is user memory
Before Redis sessions: kill Redis in staging and time impact. After: document recovery under fifteen minutes or tested Sentinel failover.
Decide and move forward without blind spots
Reserve a dedicated instance for sessions, deploy Sentinel or managed HA Redis before multi-node production, and wire an application health check with Redis alerting. Run a simulated outage each quarter, and ban any FLUSH without written procedure — mass logout often comes from an admin gesture, not an attack.
Frequently asked questions
Is Redis suitable for PHP sessions?
Yes — low latency, native TTL, shared across PHP nodes. Prefer dedicated instance or separate DB index rather than mixing cache and sessions on same keys.
What happens if Redis is unavailable?
By default, mass logout. Plan Sentinel, Cluster, AOF persistence or documented fallback with its limits.
Should sessions in Redis be encrypted?
If data is sensitive, encrypt app-side and use private network with ACL minimum.
Redis sessions vs sticky session?
Redis enables stateless PHP; sticky alone is fragile on node redeploy.
Redis sessions scale PHP — if you do not treat user state as disposable cache.