AgentSkillsCN

sfcc-caching

SFCC 统一缓存策略(页面缓存 vs 自定义缓存 vs 服务响应缓存)。适用于提升性能、减少外部调用、设计缓存键与 TTL,或调试缓存过期行为时使用。

SKILL.md
--- frontmatter
name: sfcc-caching
description: Unified caching playbook for SFCC (page cache vs custom cache vs service response cache). Use this when improving performance, reducing external calls, designing cache keys/TTLs, or debugging stale cache behavior.

SFCC Caching (Unified Playbook)

Caching in SFCC has multiple layers. The most common failures come from:

  • choosing the wrong cache layer
  • unsafe population patterns
  • invalidation assumptions (multi-node)
  • caching the wrong data types (heavy API objects)

Quick Checklist

text
[ ] Choose cache layer: page cache (HTML) vs custom cache (data) vs service response cache
[ ] Design keys with site + locale scoping where needed
[ ] Use atomic get-or-load patterns (avoid double loaders)
[ ] Cache POJOs/DTOs, not dw.* API objects
[ ] Treat cache values as immutable snapshots; re-put updated copies
[ ] Design around TTL, not cross-node invalidation
[ ] Monitor hit ratios and write failures in Business Manager

Cache Layers (Pick the Right Tool)

LayerWhat it cachesWhen to use
Page cacheRendered responses / fragmentsHigh-traffic pages where output can be cached
Custom cache (CacheMgr)Application dataExpensive computations, repeated DB lookups, third-party responses
Service response cacheHTTP responses inside service frameworkRepeated calls to stable third-party APIs

Scope: request vs session vs CacheMgr

  • request.custom: per-request scratchpad
  • session.custom / session.privacy: per-user, per-session data (keep small)
  • CacheMgr: app-server local cache shared by users on the same node

Never store user-specific data in a global custom cache.

Custom Cache Mechanics (Non-Negotiable Rules)

1) Define caches in caches.json and register in cartridge package.json

  • Cache IDs must be globally unique across the cartridge path.
  • The package.json that declares "caches" must live in the cartridge root (cartridges/{{mycartridge}}/package.json), and the caches.json path is relative to that.

2) Use atomic “get-or-load”

Prefer cache.get(key, loader) (single step). Avoid:

  • if (!cache.get(key)) cache.put(key, load())

3) Cache POJOs, not API objects

Don’t cache dw.catalog.Product, dw.order.Order, etc. Map to a lightweight object with only the fields you need.

4) Treat cached values as immutable

Values returned by cache.get are immutable copies. Do not mutate them in-place. If you need to update cached data, write a new object back with cache.put(key, newValue).

5) TTL over invalidation

Per-key invalidation across all nodes is unreliable. Design for a small staleness window using expireAfterSeconds.

6) Watch size limits and monitoring

  • Large entries can fail to store without throwing exceptions.
  • Use Business Manager stats (hit ratio, write failures) to validate effectiveness.

Service Response Caching (LocalServiceRegistry)

If your third-party data is stable for short periods:

  • Enable response caching on the underlying HTTP client in the service definition
  • Ensure you understand how to clear it (BM invalidation is typically global)

Key warnings:

  • stale data risk
  • debugging surprises (you may not hit the network)
  • cached calls can still affect service stats / circuit breakers

References