Redis et la gestion des permissions : comment réduire vos coûts d'infrastructure en optimisant vos requêtes
Dans le développement web moderne, les performances applicatives ne sont pas qu'une question de confort utilisateur. Pour une TPE ou une PME, chaque requête inutile vers la base de données représente une consommation de ressources serveur, donc un coût réel. Cet article explore une problématique concrète rencontrée dans les applications PHP — illustrée ici avec Laravel — et comment une solution de mise en cache comme Redis peut transformer la situation.
Source originale : Cet article s'inspire du benchmark publié par Sebastian Cabarcas sur dev.to, que nous adaptons ici dans une perspective Symfony/PHP et orientée impact métier.
Le problème : des requêtes SQL silencieuses qui s'accumulent
Dans la plupart des applications web, la gestion des droits utilisateurs repose sur des vérifications de permissions récurrentes. À chaque action sensible — afficher une page, soumettre un formulaire, accéder à une ressource — l'application interroge la base de données pour valider les droits de l'utilisateur connecté.
Ce comportement est tout à fait normal et attendu. Le problème apparaît à l'échelle. Voici un scénario classique :
- Un utilisateur charge une page qui effectue 10 vérifications de permissions différentes.
- Chaque vérification déclenche une requête SQL.
- Avec 100 utilisateurs simultanés, c'est potentiellement 1 000 requêtes SQL pour la seule gestion des droits, par chargement de page.
Pour une petite application avec peu de trafic, cela reste invisible. Mais dès que l'activité augmente — campagne marketing, mise en ligne d'une nouvelle fonctionnalité, croissance organique — le serveur de base de données commence à saturer. La solution immédiate et coûteuse : passer à un serveur plus puissant. L'alternative intelligente : éliminer les requêtes redondantes à la source.
Redis comme couche de cache : le principe
Redis est une base de données en mémoire, extrêmement rapide, utilisée principalement pour le cache et la gestion de sessions. L'idée est simple :
- La première fois qu'un utilisateur effectue une action nécessitant une vérification de permission, l'application interroge la base de données SQL.
- Le résultat est stocké dans Redis avec une durée de vie définie (TTL).
- Pour toutes les vérifications suivantes pendant la durée de vie du cache, l'application lit directement depuis Redis — sans toucher à la base de données.
Le gain est immédiat : la latence d'une lecture Redis est de l'ordre de 0,1 à 1 milliseconde, contre plusieurs dizaines de millisecondes pour une requête SQL sur un serveur distant ou sous charge.
Ce que montre le benchmark de Sebastian Cabarcas
Dans son dépôt de benchmark, l'auteur compare deux comportements sur une application Laravel utilisant un système de rôles et permissions :
| Scénario | Requêtes SQL par vérification | Comportement sous charge |
|---|---|---|
| Sans cache (défaut) | Multiples requêtes répétées | Dégradation rapide |
| Avec cache Redis | Quasi-zéro après le premier chargement | Stable et performant |
Le constat principal est éloquent : ce n'est pas la première requête qui pose problème, c'est la répétition des mêmes requêtes pour les mêmes données. La base de données recalcule inlassablement des informations qui n'ont pas changé entre deux requêtes HTTP.
Application concrète en Symfony : ce que cela signifie pour votre projet
Bien que le benchmark soit réalisé avec Laravel, la problématique est identique en Symfony. Le composant Security de Symfony effectue des vérifications de voters et de rôles à chaque requête. Sans cache, chaque isGranted() peut potentiellement déclencher des appels à la base de données via un voter personnalisé ou un fournisseur d'utilisateurs.
Voici les bonnes pratiques que nous appliquons chez MulerTech :
1. Mettre en cache le profil de sécurité utilisateur
Plutôt que de recharger les rôles et permissions depuis la base de données à chaque requête, on stocke dans Redis un objet représentant les droits de l'utilisateur pour la durée de sa session ou avec un TTL court (quelques minutes).
2. Invalider le cache au bon moment
La mise en cache introduit une notion de cohérence : si les droits d'un utilisateur changent (révocation d'un rôle par un administrateur), le cache doit être invalidé immédiatement. Il est essentiel de prévoir cette logique d'invalidation dans les événements métier correspondants.
3. Dimensionner le TTL selon le contexte
Un TTL de 5 à 15 minutes est souvent un bon compromis entre fraîcheur des données et réduction de charge. Pour des systèmes très sensibles aux changements de droits en temps réel, on privilégiera une invalidation explicite plutôt qu'un TTL long.
Impact financier pour une TPE/PME : des chiffres pour convaincre
Reprenons l'exemple chiffré. Supposons une application avec :
- 500 utilisateurs actifs par jour
- 20 vérifications de permissions par session
- 3 requêtes SQL par vérification (scénario sans cache)
Cela représente 30 000 requêtes SQL par jour uniquement pour la gestion des permissions. Avec Redis, ce chiffre tombe à quelques centaines de requêtes — une division par 100 ou plus.
Concrètement, cela se traduit par :
- Un serveur de base de données moins sollicité, donc potentiellement de taille inférieure.
- Des temps de réponse améliorés, ce qui réduit le taux de rebond et améliore l'expérience utilisateur.
- Une scalabilité horizontale facilitée : ajouter des serveurs applicatifs ne surcharge pas la base de données.
Pour une PME hébergeant son application sur un cloud facturé à la consommation (AWS, OVH, Azure), la réduction de la charge sur la base de données peut représenter une économie mensuelle significative, sans aucun changement fonctionnel visible pour l'utilisateur final.
Conclusion : la performance, un investissement rentable
Optimiser les requêtes de permissions via Redis n'est pas réservé aux grandes entreprises avec des équipes d'ingénierie dédiées. C'est une bonne pratique accessible, bien documentée, et au retour sur investissement rapide pour tout projet web en croissance.
Chez MulerTech, nous intégrons systématiquement une réflexion sur la stratégie de cache dès la phase de conception des projets Symfony. La mise en place de Redis pour les données fréquemment lues et rarement modifiées — comme les permissions utilisateurs — fait partie des optimisations que nous recommandons avant même que le problème de performance ne se manifeste.
Mieux vaut anticiper la charge que la subir.