Storefront Performance Collapse After Catalog Expansion
A storefront on Adobe Commerce Cloud (Starter, production) had ~20k SKUs and p95 TTFB of 400ms. After a catalog expansion to 150k SKUs and enabling 40 catalog price rules, p95 TTFB rose to 3.2s on category pages, cart page p95 is 1.8s, and Redis memory is at 92%. Full-page cache hit ratio dropped from 85% to 40%. The team disabled the FPC to 'debug' and now everything is slower. Cloud has 3 web nodes.
1. Diagnose the FPC hit-ratio collapse and the TTFB regression. What are the likely contributors and how do you confirm each?
Read the worked answer
Hit-ratio collapse causes:
- Cache key explosion: price rules and catalog changes invalidate FPC tags frequently. 40 catalog price rules that are date/time-based or customer-group-based force per-group cache variants and frequent invalidation. Confirm by inspecting cache tag invalidation logs and the number of distinct cache keys per URL.
- Customer-group / cookie variation: if rules differ by group, FPC must vary by group; guest vs. logged-in split plus group variants multiply keys.
- Catalog size: more products → more tag invalidations per save → shorter effective TTL.
TTFB regression causes:
- Category page queries now scan larger product sets; layered nav and price-rule filtering join against
catalogrule_product_pricefor 150k products × groups. Confirm with slow query log andEXPLAINon the category product collection. - Redis at 92% → eviction of cache entries, causing misses and slower reads. Confirm via Redis
INFO memoryand eviction stats.
Disabling FPC removed the cache layer entirely, so every request now hits the app - hence 'everything slower.' Re-enable FPC immediately; debug with targeted cache bypass, not global disable.
2. Propose a caching and indexing remediation plan, ordered by impact.
Read the worked answer
Ordered by impact:
- Re-enable FPC and fix invalidation, not disable it. Use targeted invalidation (product/category tags) and avoid full cache flush.
- Redis sizing/eviction: raise memory or split cache vs. session vs. FPC into separate Redis instances. At 92% with evictions, you are losing cache entries. Set
maxmemory-policyappropriately (noeviction for session, allkeys-lru for cache). Move FPC to its own Redis DB/instance so a cache flush doesn't nuke sessions. - Price rule optimization: reduce to the minimum active rules; ensure rules are indexed (
catalogruleindexer on schedule) and avoid real-time rule evaluation on category pages. Precompute rule prices into the price index. - Indexing mode: switch price/catalogrule/catalogsearch indexers to
Update by Schedule(mview) so they don't run inline and don't invalidate constantly. - Query tuning: add/verify indexes on category product and rule tables; use flat catalog for category pages if not already; paginate layered nav.
- Scale: with 3 web nodes, ensure FPC is shared (Redis) not per-node; add nodes only after cache is fixed.
Measure p95 TTFB and hit ratio before/after each step.
3. Cart page p95 is 1.8s even with FPC (cart is uncacheable). How do you improve it?
Read the worked answer
Cart is inherently uncacheable (per-customer), so FPC won't help. Focus on the quote load path:
- Quote/totals collection cost: with 40 price rules,
collectTotalsevaluates rules per item. Precompute rule prices and avoid re-evaluating rules on every cart load; cache computed rule price per product/group. - N+1 queries: profile the cart page; quote item → product → price resolution often N+1. Use collection loading with joins and
addFieldToSelectto limit attributes. - Redis session: ensure session storage is Redis (not files) and on a non-evicting instance; session reads on every cart request.
- Reduce observers: audit
checkout_cart_save_after/sales_quote_collect_totals_*observers for heavy work (like the gift module) that run on every cart load. - Customer group price resolution: ensure tier/group prices come from index, not live computation.
Target: identify the top slow query/observer via profiler (Blackfire/New Relic) and fix the single biggest contributor first. Re-measure p95.