PrestaShop full-page cache, Redis and CDN caching
Choose and verify PrestaShop cache layers, personalised bypasses, Redis integrations, session isolation, Cloudflare rules and cache clearing.
Cache public pages and repeated data only where you can keep prices, stock and customer state correct. Identify each cache layer, verify its integration and measure both cache hits and uncached requests.
What we would do
We would measure the live request path before choosing another cache. Keep a working cache if it protects correctness and reduces measured load. Use full-page caching for eligible repeated public visits, and fix expensive uncached work alongside it, especially cart and checkout. Redis is a candidate when an implemented adapter can reuse the data causing the delay.
The route depends on your existing PrestaShop and PHP releases, modules, integrations, theme, catalogue data, customer groups, markets and traffic. Include your team's ability to monitor, purge and recover each added service. An ERP stock import, country-dependent prices or a personalised header can change the safe policy even when two shops use the same cache module.
Make the change on a private staging copy with representative data and the same relevant modules, integrations and theme. Isolate its cache namespace and session storage from production, and prevent test orders, emails and exports reaching live systems. Change one layer at a time, rehearse browsing, updates and failure recovery, then plan the live switch with the previous configuration available and a named person checking orders and freshness.
If you want the bottleneck assessed before choosing a cache, the PrestaShop Speed & Core Web Vitals Audit provides a measured, prioritised fix plan; implementation is scoped separately.
Which route fits your evidence?
| What you observe | Start here | Evidence before keeping the change |
|---|---|---|
| Repeated anonymous category and product visits occupy PHP workers. | Trial eligible full-page caching at a layer your host and team can operate. | Warm hits reduce origin work; private requests bypass it and misses remain usable. |
| Uncached pages repeat expensive database reads whose results can safely be reused. | Check whether a supported persistent cache adapter covers those reads, then trial Redis or another supported backend. | Adapter-specific activity and lower query cost on those requests, with correct invalidation. |
| Checkout waits for a carrier API or a module performs expensive customer-specific work. | Profile that integration and agree which results, if any, may be reused. | The uncached purchase journey improves without reusing another customer's quote or state. |
| HTML arrives promptly but images or third-party scripts delay the visible page. | Work on assets, script execution and static CDN delivery. | Browser measurements improve; a Redis connection alone does not answer this problem. |
| You have shared hosting or no shell access. | Ask the host about managed Redis, supported PHP clients and available diagnostics. | A supported service and a measured benefit justify adoption; lack of SSH alone does not justify migration. |
| Requests move between several application servers. | Check shared cache and session requirements alongside the load-balancer configuration. | The same customer journey works across nodes, with consistent keys and a tested failure route. |
Identify the cache layer you are changing
A cache helps only when the application reads from it. Installing Redis does not automatically move every PrestaShop cache into memory.
| Layer | What it stores | What still runs on a hit |
|---|---|---|
| Browser or CDN static cache | Images, stylesheets and scripts | The HTML request can still reach the origin. |
| CDN or reverse-proxy HTML cache | Eligible HTTP page responses | A hit can be served before PHP runs. |
| PHP origin full-page cache | Rendered HTML | PHP and any bootstrap preceding the cache lookup still run. |
| Persistent query/backend cache | Eligible results selected by the integration | The application still builds the page. |
| Request-local cache | Data reused during one PHP request | It is recreated for the next request. |
| Smarty compilation and output caches | Compiled template PHP, or separately cached template output | Depends on the template's caching policy. |
| Symfony caches | Framework caches such as container and routing data | A separate object-cache adapter does not automatically replace them. |
| OPcache | Compiled PHP bytecode | PHP executes that code. |
Smarty normally reuses compiled templates. It does not compile every template on every request. PrestaShop starts Smarty with global output caching off and manages caching selectively. Use the supported back-office settings rather than changing global output caching indiscriminately.
The PrestaShop 1.7.8 and 9 Performance forms list Memcache, Memcached, APC/APCu and XCache backends, subject to installed extensions. They do not offer Redis or a filesystem backend in that selector. Legacy CacheFs is a separate implementation. Redis requires an adapter or module that implements the layer you intend to use.
Cache::store() uses a request-local array, while Configuration has static caches. Eligible database results can use the persistent Cache backend. Changing that backend does not redirect every category, hook, configuration or template lookup.
Choose a safe full-page cache policy
Full-page caching stores an eligible rendered response for later visitors. On a miss, normal rendering still happens. A PHP page cache can reduce later controller and template work while retaining bootstrap overhead. A proxy or CDN hit can bypass the origin entirely.
Start with public anonymous pages. Bypass cart, checkout, authentication, account pages, back-office routes, private module endpoints, webservices, callbacks and state-changing requests. Also account for AJAX, query parameters, preview links, session cookies and responses that set cookies.
A cache key must distinguish every context that changes the public response. Depending on your store, that can include hostname, shop, language, currency, country, tax context, device rendering and supported query parameters. Customer-group prices and personalised promotions need particular care.
Do not serve one customer's private content to another. If a context cannot be represented safely in a key, bypass it. Avoid stripping cookies merely to force a hit. Test both the cache lookup and the decision to store a newly rendered response.
Dynamic fragments, AJAX hydration, edge-side includes and personalised-request bypasses are different designs. Hydration and flicker are not inevitable properties of full-page caching. If your implementation replaces header or cart fragments after loading, reserve space and test slow devices. A visual zero cart count does not, by itself, prove that the server-side basket is empty.
Performance Revolution runs its origin page cache inside PHP after bootstrap, and its eligibility policy checks customer, cart and other request contexts. Its help page covers supported page-cache, critical-CSS, warming and CDN workflows.
Invalidation is part of the design
- Purge or update affected entries after product, category, stock, price, promotion, translation and configuration changes.
- Account for scheduled price-rule activation and expiry.
- Require imports and integrations to trigger the appropriate invalidation. Direct database writes can bypass application hooks.
- Use TTL as a freshness limit, not proof that edits become visible immediately.
- Warm only eligible public pages and avoid overwhelming the origin with simultaneous misses.
Test a price edit and a stock change through every update path you use. A manual purge can repair an incident, but recurring staleness needs an invalidation fix.
Worked example: public prices and an ERP stock import
Your shop sells to retail visitors in different countries and gives signed-in trade customers separate prices. Warm a public product and category page in each supported price context, then sign in as a trade customer. Check the rendered price, tax display and cart total against an uncached reference; the trade visit must follow the agreed bypass policy.
On staging, warm the public product and listing variants and confirm hits at each enabled HTML cache layer. Change only the price in the back office, then compare each variant with an uncached reference before any manual purge. Warm again, confirm hits, then change only stock through the actual ERP import and repeat the checks, including availability messages and edge copies. Test each update path on its own: if either leaves old data, bypass the affected page cache until that path reliably invalidates it.
Connect Redis to an implemented integration
Redis is an in-memory key-value service, run on your server or supplied by your host. It can store cache values, page-cache entries or PHP sessions when a corresponding integration uses it. First identify the adapter, supported PrestaShop/PHP versions, key format, TTL policy, invalidation and failure behaviour.
- Confirm your host supplies a reachable Redis service. A host-managed service does not require you to have SSH.
- Check the required PHP client in the web PHP runtime, not only CLI PHP. PHP-FPM and CLI can load different configuration.
- Configure host, port, authentication, TLS where required, database and namespace in the selected integration. In containers, use the correct service address; localhost refers to the current container.
- Give each installation and required shop/group scope an explicit namespace. A shared default prefix such as
ps_does not isolate shops. - Visit representative pages and verify adapter-specific keys, TTLs and reads/writes.
- Test invalidation, connection failure and recovery on staging.
Local diagnostic examples, assuming Redis is deliberately reachable on the same host at port 6379:
redis-cli -h 127.0.0.1 -p 6379 PING
redis-cli -h 127.0.0.1 -p 6379 INFO stats
redis-cli -h 127.0.0.1 -p 6379 INFO memory
redis-cli -h 127.0.0.1 -p 6379 -n 0 DBSIZE
Use your service's authentication and transport requirements. PONG confirms reachability, not that PrestaShop uses Redis. A nonzero key count can belong to another application. Inspect the selected integration's namespace and activity. Instance-wide hits and misses cannot identify one shop's benefit.
Use SCAN with a known prefix for controlled inspection. MONITOR can expose command data and add overhead; reserve short diagnostic use for a controlled environment.
Redis Cache Manager & Monitor provides administrative connection testing, monitoring and namespace/key management; its help page covers the module's workflows.
Application cache adapters, PHP session configuration and full-page caching remain separate integration work. A saved switch or a successful dashboard connection does not prove that an application cache has changed. If the expected namespace stays empty, check the selected database, prefix and page eligibility before changing capacity. Check the web runtime's connection errors and adapter configuration; installing a PHP extension alone does not add a Redis choice to the native selector.
Memcached is another in-memory cache option, with a different feature set. Both Redis and Memcached can have PHP session handlers configured separately. Choose from supported adapters, operational needs and measurements rather than assuming one is always faster.
Keep sessions, eviction and durability separate
PrestaShop carts are database records. Customer identity also involves PrestaShop cookies and database-backed records. PHP/Symfony sessions are another layer. Moving PHP sessions to Redis does not move cart rows or guarantee customer-login continuity.
If you change the PHP session handler, follow the phpredis configuration guidance for your installed version and apply it to the correct PHP-FPM pool. Verify where your application's framework expects to configure sessions.
Define session TTLs, locking, authentication, capacity, persistence and failure behaviour. Redis-backed sessions can still require locking to prevent concurrent requests overwriting state. Test parallel requests from the same session and from different sessions.
Separate Redis database numbers can help distinguish keys, but they share instance memory, eviction policy and failure exposure. A cache flush can affect sessions if the scope is wrong. Prefer a separately provisioned session service when sessions need a different durability and eviction policy.
Redis eviction policies apply to the instance. volatile-lru evicts keys with TTLs, which can include sessions. It does not protect them. Select cache eviction deliberately, and monitor write failures if a no-eviction policy is used.
For sessions, choose RDB/AOF persistence, replication and recovery objectives explicitly. Persistence reduces some loss scenarios but does not guarantee zero loss or uninterrupted logins.
On a load-balanced shop, verify that every web node uses the intended shared backend and compatible namespace. Rehearse a journey that moves between nodes. Shared PHP session storage alone cannot correct inconsistent application configuration, cookie scope or secrets, and it does not replace the database holding carts.
Size Redis using measured key counts, payload sizes, variants, TTLs and peak usage. Watch used_memory, used_memory_peak, maxmemory, evicted_keys, rejected writes and connections. Eviction can be expected in a bounded disposable cache; interpret it alongside latency and hit patterns. There is no catalogue-size memory formula or universal 90% hit-rate target.
Calculate the hit rate for an observation window as the increase in keyspace_hits divided by the combined increases in keyspace_hits and keyspace_misses, excluding windows with a counter reset or no lookups. These counters cover the whole Redis instance, not only the shop. A low reuse rate can reflect many country/currency variants or rarely revisited URLs. Correlate it with expiries, imports, purge events and memory pressure before raising maxmemory. Track connected_clients against traffic and connection errors; growth alone is not proof of a leak.
Configure Cloudflare or Varnish around the application
Cloudflare's default cache behaviour primarily targets eligible static resources; HTML caching requires deliberate configuration. Begin with static delivery and confirm that dynamic requests remain private. Use Full (Strict) TLS with a valid origin certificate and matching hostname. Flexible mode uses HTTP to the origin and can conflict with HTTPS redirects.
- Keep cart, checkout, account, admin, API, AJAX and payment callbacks out of shared HTML caching.
- Respect private/no-store directives and Set-Cookie behaviour. Test the effective edge rules, not just origin headers.
- Keep mail-related DNS records unproxied where required by the mail service.
- Restore real visitor addresses only from trusted Cloudflare proxies. Do not trust an arbitrary client-supplied forwarding header.
- Test WAF and bot rules against payment callbacks, order placement and integrations.
- Disable or explicitly exclude checkout scripts from Rocket Loader if it changes required script ordering; test the complete flow.
A controlled CDN HTML integration can mark only eligible anonymous GET/HEAD responses for caching and send bypass headers for other contexts. Configure supported purge mechanisms and verify your account's current capabilities. Headers alone do not prove that the edge cached or bypassed a response.
Varnish is an HTTP reverse proxy. On a hit it can respond before PHP runs. It needs rules for methods, cookies, cache keys, private responses, invalidation and failure behaviour. Many deployments terminate TLS in a separate component. Dynamic fragments are optional implementation work.
Add a reverse proxy when measured anonymous traffic or PHP worker saturation justifies operating it. It cannot remove uncached checkout work. Provision enough origin capacity for misses, purges and outages, and protect invalidation endpoints.
Clear and diagnose the correct cache
Start with Advanced Parameters > Performance > Clear cache. Record which symptom you are investigating. A browser refresh does not clear the origin, OPcache or edge caches.
- Use staging where possible. Change or bypass one layer at a time.
- Clear the application's supported caches and verify the page directly at the origin through your authorised diagnostic route.
- Invalidate any separate module or Redis namespace involved.
- Reset web OPcache only if the deployment requires it. A CLI
opcache_reset()normally does not reset the web PHP-FPM pool. - Purge affected proxy/CDN entries after the origin is correct.
- Recheck a fresh anonymous request and a personalised request, then restore the intended settings.
var/cache/prod and var/cache/dev remain active for framework and Smarty caches after a separate Redis adapter is installed. Older 1.6 layouts use cache/smarty; legacy CacheFs uses cache/cachefs. Confirm your exact release and root before any filesystem cleanup.
Prefer the supported cache-clear operation. If recovery requires manual cleanup, isolate the site, preserve the directory structure and access controls, run as the application user and verify ownership and cache rebuilding. Do not apply an unscoped recursive deletion from an uncertain working directory.
Use integration-aware namespace invalidation. FLUSHDB deletes every key in the selected database; FLUSHALL deletes every database on the instance. Neither is a safe substitute for a shop-scoped purge on shared infrastructure.
If caching returns incorrect prices, personal information or checkout state, bypass the affected layer until corrected and verified. Production cache settings should follow correctness and measured load, rather than an unconditional rule to leave every cache enabled.
Measure performance and fix uncached work
Record cold and warm responses for the same URLs, data, language, currency, device and login state. Include concurrency, origin load and cache status. Compare ordinary browsing with cart and checkout requests. Measure repeated trials rather than a single request.
TTFB measures the delay until the response begins. It supports loading diagnosis but is not a Core Web Vital. The Core Web Vitals are LCP, INP and CLS. Report LCP and INP as time, CLS as a unitless value, and a Lighthouse performance score separately. Better scores do not guarantee rankings.
Use the legacy PrestaShop profiler for ordinary legacy storefront requests, on protected staging. Use Symfony profiling for requests handled through Symfony. Production APM, slow-query logs and web-server metrics can help without exposing a debug page.
- Profile costly hooks, repeated queries and live external calls. Cache only data whose freshness and scope you can define.
- Fix missing indexes and expensive queries. Apply a retention policy before cleaning logs, mail records or connection data.
- Use supported Smarty compilation settings and clear compiled templates after deployment where needed.
- Enable and size OPcache for the web runtime. JIT is separate and needs an application benchmark. If timestamp validation is disabled, reset OPcache reliably during deployment.
- Choose PHP from the exact release's compatibility matrix. PrestaShop 1.7.8 does not officially support PHP 8.
- Tune MySQL against your workload and total memory budget. MySQL 8.0.30+ uses
innodb_redo_log_capacity; MariaDB and older MySQL releases differ. - Test CSS/JavaScript optimisation, critical CSS, responsive images and third-party scripts. Reserve image dimensions and dynamic UI space to limit layout shifts.
If enabling a cache leaves the same request slow, profile the cache machinery too: key building, serialisation, locks and repeated asset hashing can add work on the request path. Compare that cost with the work saved, including on a miss.
A cache can reduce repeated work while slow misses remain. Keep it when it improves measured performance safely; remove or replace it only after testing the resulting load and customer experience.
Rehearse the switch and hand over recovery
- Record the current settings, request timings and cache status for representative home, category and product pages, plus a cart and checkout. Keep the exact test contexts so the comparison can be repeated.
- On staging, warm the intended public variants. Use separate browser profiles for anonymous visitors and customers with different groups or currencies. Check cart, login and personalised header behaviour as well as the page body.
- Run updates through the back office, scheduled promotions and each import or integration you use. Check the application cache and any proxy/CDN copy against the expected current data.
- Rehearse a purge and cold browsing under representative concurrency. Then make Redis or the page-cache service unavailable in the controlled environment and verify errors, fallback load and recovery separately for each enabled layer.
- Agree the live window, rollback trigger and responsible person. Apply the tested configuration, invalidate or warm only the intended scope, and check real browsing, purchases and the next import after the switch.
A rollback for disposable cached HTML can mean bypassing that layer and purging its copies. A session-handler rollback needs its own procedure: the previous store may not hold sessions created after the switch. Agree continuity expectations before changing handlers, and rehearse both directions. Do not replace the live database with the staging database to launch a cache configuration.
What to ask your developer or agency
- Which layer changes, where does a hit stop processing, and what continues running?
- Which request contexts are keyed or bypassed, and where is the evidence that private content cannot enter shared storage?
- Which updates invalidate which copies, and who owns invalidation for ERP imports and scheduled promotions?
- What happens during a purge, cache outage or session-handler rollback, and can the origin carry the resulting load?
- Where are the tested settings, namespace map, monitoring, scoped purge instructions and recovery procedure recorded for staff?
Questions owners ask
Which cache should I buy first?
Choose from the request that is slow and the work it repeats. Ask for a baseline and a reversible trial before buying infrastructure or another module. If the diagnosis is unclear, use the performance guide to organise the measurements.
Does Redis replace OPcache or the database?
No. OPcache reuses compiled PHP code; a Redis integration reuses selected values or stores sessions. The database still holds your shop records, and uncached requests still need enough capacity.
Why is a repeat visit fast while a new visitor still waits?
The repeat may hit a browser, page or data cache that the new request misses. Check the actual cache status and visitor context, then compare cold and warm results. Your own warm browser is not evidence of the first-visit experience.
Should I leave every cache enabled during a fault?
Bypass the layer serving incorrect or private content, then investigate it with an uncached reference. Check the origin's load while it carries more requests, and restore the tested policy after the fault is fixed.
Can I remove full-page caching after the shop is tuned?
Trial bypassing it on staging under representative load first. Keep or remove it according to correctness, peak capacity and customer experience; a faster uncached page alone does not show that peak traffic is covered.