Table des matières :
- Cartographie des couches de cache côté serveur dans PrestaShop
- Varnish devant PrestaShop : cache HTTP, contournements et invalidation réaliste
- Redis vs Memcached : cache objet, sessions PHP, et limites du cache natif PrestaShop
- OPcache : le gain “facile” côté PHP-FPM, et les pièges en déploiement
- Mesure, observabilité et garde-fous : sinon vous optimisez à l’aveugle
- Combinaisons recommandées (sans folklore) selon vos contraintes d’exploitation
Cartographie des couches de cache côté serveur dans PrestaShop
Sur une stack PrestaShop moderne (exemples validés ici avec PrestaShop 9.1 et PHP 8.2 en mode PHP-FPM), il faut raisonner en couches : cache HTTP (reverse proxy), cache applicatif (Smarty/Symfony), cache objet (Redis/Memcached), et cache d’exécution PHP (OPcache). Mélanger ces sujets sans clarifier “qui cache quoi” mène presque toujours à des incohérences (panier affiché d’un autre utilisateur, prix non à jour, ou invalidations impossibles à maintenir).
Pour cadrer rapidement, la grille suivante évite 80% des confusions lors d’un audit :
| Couche | Où ça vit ? | Ce que ça accélère vraiment | Ce que ça ne règle pas | Risque principal |
|---|---|---|---|---|
| Varnish (HTTP cache) | Devant le serveur web | Pages publiques identiques (home, catégories, produits non personnalisés) | SQL lent, PHP lent sur miss, pages personnalisées | Mauvais bypass → fuite de personnalisation / bugs |
| Cache applicatif PrestaShop (Smarty/Symfony) | Dans l’app (fichiers, var/cache) | Templates compilés, certains fragments/containers | Full-page caching robuste, invalidation métier globale | Invalidation partielle → incohérences |
| Redis/Memcached (cache objet & sessions) | Service RAM | Sessions partagées, objets réutilisés, configuration | Requêtes non cacheées, logique métier coûteuse | Eviction/latence → effet domino sur PHP-FPM |
| OPcache | Dans PHP-FPM | CPU (compilation PHP), autoload, gros codebase | Réseau, DB, I/O externes | Bytecode stale après déploiement si mal géré |
Le point clé : PrestaShop, même en v9, n’est pas un CMS “headless-friendly” avec une stratégie de cache unifiée. Le cœur mélange encore du legacy (Smarty, contrôleurs historiques) et des briques Symfony. Résultat : le cache applicatif natif reste partiel. Vous pouvez activer le cache dans Paramètres avancés > Performances, mais cela n’équivaut ni à du full-page caching fiable ni à une politique d’invalidation robuste. Le gros des gains, en production, vient généralement de Varnish (TTFB, pics de trafic) et de OPcache (CPU), puis de Redis (sessions + objets) si votre hébergement et vos modules le tolèrent.
D’un point de vue standards HTTP, le cadre est clair :
“HTTP caches are used to reduce response time and network bandwidth requirements on future, equivalent requests.” — RFC 9111 (HTTP Caching), IETF, 2022 (https://www.rfc-editor.org/rfc/rfc9111)
PrestaShop, lui, n’émet pas toujours des en-têtes de cache exploitables pour des pages HTML dynamiques, et la présence de cookies (session, consentement, comparateur, modules tiers) détruit la cacheabilité si vous ne fixez pas explicitement une stratégie de contournement. En pratique, sur un front e-commerce, on voit souvent des cookies “non essentiels au rendu” (tracking, A/B test, consent) se retrouver sur toutes les pages : si Varnish les prend au pied de la lettre, vous vous retrouvez avec une variante par visiteur… donc zéro hit ratio.
Pour replacer le sujet dans une démarche de performance mesurable (TTFB, ratio de hit, CPU), vous pouvez recouper avec vos méthodes de monitoring et tests de charge : https://www.expertise-prestashop.fr/2026/06/18/prestashop-performance-monitoring-tests-de-charge-et-runbooks-soldes/ et votre objectif TTFB : https://www.expertise-prestashop.fr/2026/06/03/ttfb-prestashop-reduire-le-time-to-first-byte-sous-200-ms/
Varnish devant PrestaShop : cache HTTP, contournements et invalidation réaliste
Varnish est un accélérateur HTTP (reverse proxy) : il se place devant Nginx/Apache/PHP-FPM et sert des réponses depuis la RAM quand elles sont cacheables. C’est le seul composant de cette liste capable de produire un gain massif sur des pages HTML quasi-statiques (home, catégories, fiches produit publiques), à condition d’accepter une contrainte : la cacheabilité n’est pas magique, elle se pilote.
Sur PrestaShop, le problème n°1 est le bypass : panier, checkout, compte, comparateur, pages “personnalisées” et toutes les requêtes avec cookies doivent généralement contourner le cache (ou passer par ESI / variations). Sans ce travail, vous aurez soit un hit ratio proche de zéro (donc complexité inutile), soit des bugs de personnalisation (donc incident). Le problème n°2 est l’invalidation : PrestaShop n’a pas de système natif propre pour purger Varnish sur les événements métier (mise à jour de prix, stock, règles panier, CMS). Vous devez l’implémenter (module + hooks), sinon vous acceptez un TTL court… qui réduit l’intérêt.
- Pages “public cacheables” : home, catégories, produit, CMS (tant qu’elles ne varient pas par utilisateur).
- Pages “toujours pass” : panier, commande, compte, login, recherche, comparateur, tout ce qui dépend fortement des paramètres utilisateur.
- Zones “fragmentables” : header, minicart, bloc compte, recommandations — typiquement en ESI.
Configuration typique (schéma minimal) :
- Varnish écoute en :80
- Nginx/Apache écoute en :8080 (backend)
- Varnish met en cache les pages publiques, bypass dès qu’un cookie “session” ou “cart” est présent
Exemple de logique VCL (à adapter, Varnish 7.x ; ici l’idée compte plus que la recette copiée-collée) :
sub vcl_recv {
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Bypass pour le tunnel, les endpoints sensibles
if (req.url ~ "^/(panier|commande|mon-compte|connexion|module/)") {
return (pass);
}
# Bypass si session / panier (noms variables selon config/modules)
if (req.http.Cookie ~ "(PHPSESSID|PrestaShop-)") {
return (pass);
}
}
sub vcl_backend_response {
# Cache HTML public pendant 5 min, à ajuster
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 300s;
}
# Respecter les réponses non cacheables
if (beresp.http.Set-Cookie) {
set beresp.ttl = 0s;
return (deliver);
}
}
Dans beaucoup de boutiques, le “gros levier” pour remonter le hit ratio n’est pas d’ajouter des règles, mais de réduire la variabilité artificielle :
- Normaliser les paramètres : ignorer (ou purger) les paramètres de tracking (
utm_*,gclid) en cache, sinon chaque campagne crée une clé différente. - Gérer les cookies de consentement : si un cookie “consentement” est présent partout, il faut souvent le whitelister (ne pas le faire entrer dans le hash), tout en gardant le bypass strict pour les cookies de session/panier.
- Marquer le résultat : ajoutez des en-têtes de debug (
X-Cache: HIT/MISS,X-Cache-TTL) en interne pour corréler vite avec vos mesures (et éviter de “croire” que Varnish sert alors que tout passe).
Dès que vous voulez dépasser le “TTL arbitraire”, vous devez traiter l’invalidation. Deux approches :
1) PURGE ciblé (sur URL) déclenché par hooks PrestaShop (update produit/catégorie/CMS). C’est simple mais vite incomplet.
2) BAN (sur tags) si vous taggez vos réponses (via X-Cache-Tags) — plus scalable, mais demande une discipline côté app.
Un mini-scenario typique en e-commerce : vous mettez une promo à 10h00 sur une catégorie, votre TTL est à 10 minutes “pour être safe”, et vous recevez un flux de trafic SEO + ads. Sans invalidation, vous avez 10 minutes de prix incohérents (support client, annulations) ou vous abaissez le TTL à 30s (hit ratio qui chute). La purge métier (au minimum sur les URL clés) évite ce compromis permanent.
Pour le caching par fragments (minicart, header “connecté”, recommandations), ESI est souvent la voie pragmatique quand on ne veut pas réécrire le thème. Voir l’article dédié : https://www.expertise-prestashop.fr/2026/05/22/varnish-cache-configuration-esi-pour-optimiser-le-cache-par-fragments/
Attention sécurité : n’exposez jamais PURGE publiquement. ACL stricte sur IP d’admin/CI, authentification éventuelle, et journalisation. Si votre architecture inclut déjà un load balancer, distinguez bien les rôles : HAProxy peut faire du routage/healthcheck/SSL offload, mais n’est pas Varnish (pas le même moteur de cache) : https://www.expertise-prestashop.fr/2026/06/22/haproxy-3-2-deploiement-systemd-configuration-frontend-backend-acl/
À garder en tête également : le cache HTTP ouvre une surface d’attaque (cache poisoning, variations involontaires). Pour une vue d’ensemble des risques et des patterns de protection, la page OWASP sur le sujet est un bon point de départ : https://owasp.org/www-community/attacks/Cache_Poisoning
Redis vs Memcached : cache objet, sessions PHP, et limites du cache natif PrestaShop
Redis et Memcached sont souvent mis dans le même panier (“cache en RAM”), mais l’impact opérationnel n’est pas le même. Redis est un data store avec persistance optionnelle, réplication, structures avancées, et tooling ; Memcached est volontairement plus simple (key/value en RAM), souvent performant, mais avec moins d’options d’architecture.
“Redis is an in-memory data structure store, used as a database, cache, and message broker.” — Documentation Redis (https://redis.io/docs/latest/)
Dans PrestaShop, deux usages reviennent :
1) Sessions PHP dans Redis : c’est souvent le gain le plus “propre” en cluster (multi frontaux) parce que vous supprimez le couplage au filesystem local. Avec PHP-FPM, cela se fait via session.save_handler = redis et un session.save_path adapté. Ajoutez le verrouillage de session (sinon, sur des pages qui déclenchent des requêtes parallèles, vous pouvez introduire des race conditions) ; par exemple avec l’extension php-redis :
; /etc/php/8.2/fpm/conf.d/zz-session-redis.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?database=2&prefix=ps_sess_"
redis.session.locking_enabled = 1
redis.session.lock_retries = 10
redis.session.lock_wait_time = 2000
Deux garde-fous simples côté exploitation :
- Séparez au minimum sessions et cache objet (bases distinctes ou instances distinctes), pour éviter qu’une éviction liée au cache ne casse des parcours de commande.
- Mettez Redis sur réseau privé, avec un
bindapproprié et une authentification si besoin : l’enjeu n’est pas la performance, c’est la réduction du risque d’exposition.
2) Cache objet via le mécanisme Cache de PrestaShop : c’est plus délicat. Le cœur a historiquement supporté plusieurs backends, mais la couverture fonctionnelle est inégale (toutes les requêtes ne passent pas par un cache), et des modules font parfois des hypothèses sur le stockage (filesystem) ou invalident trop agressivement. En clair : activer Redis/Memcached dans PrestaShop peut aider sur la configuration, certains calculs, certaines données réutilisées… mais ne remplace pas un audit SQL (index, N+1, surcharges). Pour l’optimisation DB, vous avez une base méthodologique ici : https://www.expertise-prestashop.fr/2026/05/25/index-mysql-optimiser-where-join-et-order-by-avec-explain/
Choix Redis vs Memcached dans un contexte PrestaShop :
- Redis : meilleur pour sessions, environnements multi-nœuds, besoin de réplication/failover, observabilité riche (
INFO,SLOWLOG). Risque : mauvaise politique d’éviction, fragmentation mémoire, et latences si vous surchargez Redis avec autre chose (queues, locks) sans dimensionner. - Memcached : très simple, efficace pour du pur cache volatile. Risque : absence de persistance (normal), invalidation “tout ou rien” dans beaucoup de setups, et moins d’outils pour des stratégies avancées.
Dans les deux cas, définissez un budget : taille mémoire, politique d’éviction (allkeys-lru/volatile-lru côté Redis selon votre usage), et isolez les bases (database=2 pour sessions, database=3 pour cache objet) ou au minimum des prefixes stricts. Et surtout : prévoyez un mode dégradé. Un Redis down ne doit pas faire tomber le front.
Checklist “cache objet” réaliste avant d’activer en prod :
- Vérifier que les modules critiques (paiement, search, pricing) ne dépendent pas d’un cache filesystem “local”.
- Tester un redémarrage Redis en heure creuse : que se passe-t-il côté sessions, panier, et backoffice ?
- Surveiller l’évolution de
evicted_keyspendant un test de charge (sinon vous “validez” un cache qui s’effondre au premier pic).
Testez explicitement les scénarios de panne dans vos runbooks (voir approche “soldes”/charge) : https://www.expertise-prestashop.fr/2026/06/18/prestashop-performance-monitoring-tests-de-charge-et-runbooks-soldes/
OPcache : le gain “facile” côté PHP-FPM, et les pièges en déploiement
OPcache n’accélère ni le réseau ni MySQL : il réduit le CPU en évitant à PHP de re-parser et re-compiler les scripts à chaque requête. Sur PrestaShop (beaucoup de fichiers PHP, autoload Composer, templates Smarty compilés), le gain est immédiat si vous partez d’un hébergement mal configuré.
“OPcache improves PHP performance by storing precompiled script bytecode in shared memory…” — PHP Manual, OPcache (https://www.php.net/manual/en/book.opcache.php)
Configuration de base (PHP 8.2 / PHP-FPM), à adapter à la taille du codebase + modules :
; /etc/php/8.2/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=60000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.fast_shutdown=1
En production “disciplinée” (CI/CD, releases immuables, symlink current), vous pouvez désactiver la validation des timestamps (validate_timestamps=0) pour gagner encore, à condition de purger OPcache à chaque déploiement (reload PHP-FPM, opcache_reset() via endpoint sécurisé, ou redémarrage contrôlé). Ne faites pas ça si vous déployez “à la main” en écrasant des fichiers : vous allez servir du vieux bytecode.
- OPcache saturé (
max_accelerated_filestrop bas, oumemory_consumptionsous-dimensionné) : vous perdez le bénéfice et vous introduisez des comportements non déterministes. Surveillezopcache_get_status()et les métriques “wasted memory”. - Préchargement/JIT : le preload peut aider sur des apps très stables, mais PrestaShop + modules + overrides = surface de variabilité importante. Le JIT est rarement un game changer pour du code I/O-bound (DB + réseau), donc ne le mettez pas en prod “par principe”. Mesurez.
Un point souvent oublié : OPcache “cache du PHP”, mais pas les templates Smarty au sens HTML (Smarty compile en PHP et ça bénéficie indirectement d’OPcache, mais la stratégie de compilation/clear cache Smarty reste à gérer via les réglages PrestaShop et votre process de déploiement). Même logique côté Symfony : var/cache/prod doit être traité proprement (warmup éventuel, invalidations maîtrisées) si vous voulez éviter des pics de latence au premier hit après release.
Si vous avez déjà eu des écrans blancs ou des pages HTML vides après modifications serveur, la discipline “config + logs + rollback” est non négociable. Référez-vous à votre checklist de diagnostic serveur/CMS : https://www.expertise-prestashop.fr/2026/06/24/page-vide-html-detection-derreurs-de-rendu-serveur-et-cms/ et à la configuration d’erreurs PHP en prod : https://www.expertise-prestashop.fr/2026/04/02/gestion-derreur-php-bonnes-pratiques-et-configuration-developpement-production/
Mesure, observabilité et garde-fous : sinon vous optimisez à l’aveugle
Un cache “qui marche” n’est pas un cache “utile”. Vous devez piloter au minimum : hit ratio, TTFB, latence backend, erreurs, et évictions. Sans ça, vous ne saurez pas si Varnish cache vraiment (ou passe tout), si Redis sert à autre chose qu’à consommer de la RAM, ou si OPcache thrash.
Un socle simple de KPI (à adapter à votre contexte) :
- Varnish :
cache_hit / (cache_hit + cache_miss)sur pages publiques + distribution de latence (p95). - Backend : temps de réponse Nginx/Apache vers PHP-FPM (logs), et saturation FPM (queue, workers occupés).
- Redis :
keyspace_hits,keyspace_misses,evicted_keys, latence, etused_memory_peak. - OPcache : taux d’occupation mémoire,
oom_restarts, et “wasted memory”.
Côté Varnish : varnishstat (hit/miss), varnishlog (diagnostic fin), varnishhist (latences). Ce que vous cherchez : un hit ratio élevé sur les pages publiques, une baisse du TTFB côté client, et une réduction des requêtes PHP-FPM. Si votre objectif est un TTFB < 200 ms, ça se prouve : mesure RUM (web-vitals) + synthetic (k6, curl chronométré) + logs serveur. Pour la partie mesures navigateur : https://www.expertise-prestashop.fr/2026/05/18/devtools-methodes-professionnelles-pour-mesurer-et-optimiser-les-performances-web/ et pour relier ça aux Core Web Vitals : https://www.expertise-prestashop.fr/2026/04/16/core-web-vitals-actions-concretes-pour-ameliorer-lcp-inp-et-cls/
Astuce très pragmatique : exposez (au moins en interne) un header du type X-Cache: HIT/MISS et X-Cacheable: yes/no pour éviter les discussions “au ressenti”. C’est particulièrement utile quand des cookies de modules tiers viennent dégrader la cacheabilité sans que personne ne l’ait prévu.
Côté Redis : redis-cli INFO, suivi des keyspace_hits, keyspace_misses, evicted_keys, latence (latency doctor) et SLOWLOG. Un pattern classique en e-commerce : vous dimensionnez Redis pour 1–2 Go, puis un pic de trafic + un module bavard remplit le cache et déclenche de l’éviction en boucle → latence augmente → PHP-FPM sature. Si vous voyez evicted_keys monter pendant un pic, vous êtes déjà en train de perdre.
Côté OPcache : exposez des métriques (Prometheus exporter ou endpoint interne), surveillez opcache_statistics.num_cached_scripts, oom_restarts, et la “wasted memory”. En cas d’incident post-déploiement, votre runbook doit inclure : rollback release, reload PHP-FPM, purge sélective Varnish, et invalidation Smarty/Symfony si nécessaire. L’objectif est la réversibilité, pas l’optimisation héroïque.
Combinaisons recommandées (sans folklore) selon vos contraintes d’exploitation
Pour une boutique “standard” (trafic modéré, 1 serveur) : OPcache est obligatoire, et c’est généralement le meilleur ROI/risque. Ajoutez éventuellement Redis pour les sessions si vous prévoyez de scaler horizontalement, mais ne vous attendez pas à une révolution sur le front si votre goulot est MySQL ou des modules lents. Si votre TTFB est haut, commencez par l’analyse (profiling, logs) avant de “rajouter un cache” : c’est une erreur de diagnostic courante.
Pour une boutique avec catalogue conséquent et pages publiques très consultées (SEO, comparateurs, campagnes) : Varnish devient pertinent. Vous visez un hit ratio élevé sur home/catégories/produits non personnalisés, et vous acceptez une stratégie stricte : bypass dès qu’un cookie de session est présent, et invalidation contrôlée. En pratique, sur des sites où 70–90% du trafic est “anonyme”, Varnish peut diviser la charge PHP par 5 à 20 et ramener le TTFB de plusieurs centaines de ms à ~50–150 ms sur hits (selon réseau). Ce n’est pas garanti : c’est ce que vous mesurez.
Pour éviter l’effet “Varnish installé mais inutile”, une check-list courte fonctionne bien :
- Décider explicitement ce qui est cacheable (et ce qui ne l’est pas).
- Normaliser URL/paramètres (sinon explosion de variantes).
- Définir une stratégie d’invalidation (au minimum sur contenus critiques).
- Mettre en place des indicateurs (hit ratio + TTFB + backend requests).
Pour une architecture multi-frontaux (2+ serveurs web) : Redis (sessions) + OPcache sur chaque nœud + éventuellement Varnish en frontal (ou par nœud selon design) devient la base. Ajoutez des garde-fous : limitation du purge, WAF, règles de sécurité sur endpoints d’admin et API, et journalisation. Sur ce point, recoupez avec votre approche sécurité API/backoffice et WAF : https://www.expertise-prestashop.fr/2026/05/29/securite-prestashop-proteger-api-backoffice-waf-et-journalisation-siem/ — parce qu’un cache mal configuré peut aussi amplifier un trafic hostile (cache poisoning, bypass volontaire, purge abusif) et transformer un incident applicatif en incident d’infra.
Enfin, ne sous-estimez pas la dette technique PrestaShop : entre overrides, modules et thèmes, votre cache policy doit être traitée comme du code (versionnée, revue, testée). Si vous envisagez une refonte lourde parce que la performance est structurellement bloquée (catalogue énorme, personnalisation front, exigences API), posez aussi la question du coût d’opportunité : https://www.expertise-prestashop.fr/2026/06/03/migration-prestashop-vers-sylius-criteres-roi-et-cas-dusage/ — pas pour “vendre” un move, mais pour cadrer quand l’empilement de caches devient un pansement permanent.




