Si tu utilises les sessions Redis dans Laravel et que tu as un setup un peu propre avec deux connexions Redis (typiquement « default » pour la data, « cache » pour… le cache), tu peux te faire avoir après une mise à jour Laravel : les sessions peuvent basculer sur la connexion « cache » sans que tu n’aies explicitement changé ta config.
Le genre de bug que tu découvres au pire moment. Des users qui se font déconnecter « au hasard », des sessions qui expirent trop vite, des “remember me” qui ne tient plus, ou un Redis « cache » qui se met à swapper parce que tu y as collé un flux de sessions que tu n’avais pas prévu.
Le changement : en Redis, « pas de SESSION_CONNECTION » ne veut plus dire « default »
Le point clé, c’est le comportement par défaut quand SESSION_CONNECTION est à null (donc non défini). Avant, beaucoup de gens vivaient avec l’idée implicite suivante : « si je ne dis rien, les sessions Redis iront sur la connexion default ». Et dans plein de projets, ça a été vrai pendant longtemps… parce que « default » et « cache » pointaient sur le même Redis, ou parce que le framework retombait sur default.
Depuis Laravel 13.3+, il y a un changement de comportement rapporté côté framework : si SESSION_CONNECTION n’est pas défini, les sessions Redis peuvent se retrouver à utiliser la connexion cache par défaut. Si chez toi cache et default sont réellement deux mondes séparés, tu viens de changer d’infrastructure… sans le vouloir.
Et le pire, c’est que la plupart du temps ça ne “crashe” pas. Ça fonctionne. Ça fonctionne juste différemment, avec des effets de bord très difficiles à relier à “une update Laravel”.
Sponsorisé par Le Scribouillard
Besoin de contenu optimisé SEO ?
Utilisez la meilleure plateforme française de création de contenu assistée par IA ! Et générez des articles pour moins de 1€ !
Pourquoi ça casse les setups multi-Redis (et pas juste « ça marche ou ça marche pas »)
Quand tu sépares Redis, ce n’est pas pour faire joli dans database.php. Tu le fais parce que tu veux isoler des usages qui n’ont pas les mêmes contraintes. Le cache, tu acceptes de le perdre, tu acceptes un eviction agressif, tu acceptes un Redis partagé, parfois même un cluster géré à part. Les sessions, c’est une autre histoire : tu veux de la stabilité, des TTL cohérents, et tu n’as généralement pas envie qu’une montée en charge “cache” dégage des sessions au passage.
Donc quand Laravel décide soudainement que “sessions Redis” = “connexion cache”, ça peut te provoquer des symptômes vicieux.
Le plus classique : ton Redis « cache » a une politique d’éviction type allkeys-lru ou volatile-lru avec un maxmemory calibré pour… du cache. Les sessions, elles, arrivent en volume, avec des TTL, et elles se font éjecter sous pression mémoire. Résultat : utilisateurs déconnectés, CSRF token qui saute, UX qui part en vrille, et côté app tu ne vois pas forcément d’erreur explicite. Juste des “sessions null”.
Autre cas réel : ACL/permissions différentes. Tu as donné à l’app un user Redis très limité sur la connexion « cache » (ou l’inverse). Ou tu as mis « cache » sur une base Redis (DB index) différente, avec des scripts de purge (un FLUSHDB “cache” en cron, j’ai déjà vu). Tes sessions arrivent pile dans le périmètre qui se fait nettoyer.
Et si tu es en infra un peu sérieuse, ça peut aussi être un sujet de latence. Certains mettent « cache » sur un Redis managé/clusterisé différent (parfois plus loin, parfois avec une config réseau différente), alors que « default » est local au VPC ou sur une instance proche. Déplacer les sessions, c’est déplacer une partie du trafic “auth” de ton app. Ça se voit.
Le fix le plus rentable : rendre SESSION_CONNECTION explicite
La bonne nouvelle : le fix est simple. La mauvaise : il est simple quand tu sais que le problème existe.
Si tu veux que tes sessions restent sur default, dis-le. Ne laisse pas une valeur implicite décider à ta place. Dans un projet un peu durable, je préfère largement “une ligne d’env en plus” plutôt que “un comportement par défaut qui bouge”.
# .env
SESSION_DRIVER=redis
SESSION_CONNECTION=defaultÇa règle déjà une grosse partie des surprises.
Et si tu veux être encore plus propre (et franchement, c’est souvent le meilleur choix), crée une connexion Redis dédiée aux sessions. Comme ça, tu peux séparer maxmemory, eviction, ACL, monitoring, et tu sais exactement où vivent tes sessions.
// config/database.php
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_CACHE_HOST', '127.0.0.1'),
'password' => env('REDIS_CACHE_PASSWORD'),
'port' => env('REDIS_CACHE_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
'sessions' => [
'host' => env('REDIS_SESSIONS_HOST', '127.0.0.1'),
'password' => env('REDIS_SESSIONS_PASSWORD'),
'port' => env('REDIS_SESSIONS_PORT', 6379),
'database' => env('REDIS_SESSIONS_DB', 2),
],
],Ensuite tu pointes SESSION_CONNECTION=sessions et tu arrêtes de mélanger des workloads qui n’ont rien à faire ensemble.
Les effets de bord à vérifier après le switch : TTL, eviction, préfixes, ACL
Quand les sessions changent de Redis, tu ne dois pas juste vérifier “ça log in”. Ça, c’est le test qui ment. Ce que tu veux savoir, c’est si ton comportement reste stable sous la vraie vie.
D’abord, regarde le couple TTL de session et politique d’éviction. Le TTL vient de ta config Laravel (souvent SESSION_LIFETIME en minutes). Si ton Redis “cache” est calibré pour des TTL courts ou pour évincer agressivement, tu vas perdre. Et ça ne se verra pas forcément en dev, parce que tu n’es jamais en pression mémoire.
Ensuite, les préfixes. Beaucoup d’équipes utilisent des préfixes Redis différents entre cache et data, parfois aussi entre environnements. Si tu bouges de connexion, tu bouges potentiellement de préfixe, donc tu changes l’espace de clés. Ça peut être un non-sujet… ou une source de collisions si tu avais déjà des clés “session-like” dans le cache. Et si tu fais du multi-tenant ou du multi-app sur le même Redis, là, c’est carrément un point de sécurité/isolement.
Et oui, pense ACL. Si ton Redis “cache” autorise moins de commandes, ou est derrière un proxy géré différemment, tu peux te retrouver avec des erreurs sporadiques ou des timeouts. Le genre de truc qui se traduit par « aléatoirement, l’utilisateur est déconnecté ». Même combat si tu as un job qui purge le cache “sans nuance”. Une purge cache qui touchait des données non critiques devient soudain une purge de sessions.
Tester en staging sans se raconter d’histoires : login, refresh, remember me
Le test utile, c’est celui qui ressemble à ce qui te fera souffrir en prod.
Je valide toujours le cycle complet : login, navigation, refresh de page (donc régénération éventuelle de session / lecture de session), expiration attendue, et surtout “remember me” si tu l’utilises. Le “remember me” te donne vite des indices : si les sessions sautent, tu vas voir des comportements incohérents, du type utilisateur “parfois connecté” selon la route, ou re-login beaucoup trop fréquent.
Si tu peux, mets un peu de charge en staging, même un truc bête. Le but n’est pas de faire du benchmark de thèse. Le but est de provoquer les conditions où Redis « cache » commence à évincer, où la latence monte, où tu vois si ton infrastructure tient quand l’auth devient bavarde. Beaucoup de régressions “sessions” n’apparaissent que quand le cache est déjà chaud et que la mémoire est sous tension.
Et pendant que tu testes, garde un œil sur Redis côté métriques. Nombre de clés, hits/misses, eviction count, mémoire utilisée. Si tu vois les evictions monter pendant que tu joues avec l’auth, tu as déjà une réponse.
Mon avis : ne laisse pas « default vs cache » décider d’un truc aussi sensible que l’auth
Ce changement de comportement est le genre de détail qui rappelle un truc simple : dans Laravel, Redis sert à plein de choses, et toutes n’ont pas le même niveau de criticité. Le cache, tu peux le jeter. Les sessions, non.
Donc ma recommandation est assez tranchée : si tu utilises Redis pour les sessions, rends la connexion explicite. Et si tu as une infra un peu segmentée, crée une connexion dédiée “sessions”. Tu gagnes en lisibilité, en contrôle, et tu te protèges des “petits” changements implicites qui deviennent des incidents.
La suite logique, si tu veux pousser la démarche, c’est de regarder ton contrat de session comme un composant à part entière : SLA, monitoring, et une stratégie claire en cas de purge ou de failover Redis. Ce n’est pas glamour, mais ça évite des semaines de bugs fantômes.