SHOPin Logo
Skip to main documentation content

Cache strategies

In the SHOPin storefront accelerator, several caches stack on top of each other. They do not share invalidation—mixing them up leads to stale UI, wrong privacy boundaries, or extra load on the BFF and upstreams. This page is a layer map; headers and edge behavior are expanded under CDN configuration.

Further reading: NestJS caching, TanStack Query — caching examples.


Next.js Data Cache (server)

  • Role — Caches fetch results during RSC / server rendering.
  • Use — Shared data with a freshness window (e.g. PLP/PDP, i18n): fetch(..., { next: { revalidate, tags } }).
  • InvalidaterevalidateTag / revalidatePath from next/cache, or revalidate TTL.
  • Avoid — Per-user or private data: noStore() or fetch(..., { cache: 'no-store' }).
  • Note — Independent of Cache-Control on the HTML response.

Next.js full route cache / HTML (HTTP)

  • Role — Browser and CDN reuse of rendered HTML (and related route cache rules).
  • Use — Pages where the same HTML is safe for many users (marketing, mostly static).
  • ConfigureCache-Control via next.config.ts headers or middleware.
  • Avoid — Authenticated or personalised HTML: no-store (or equivalent).
  • Note — Does not control the Data Cache; only HTTP caching of that response.

React Query (client)

  • Role — Per-tab client cache (dedupe, staleTime, refetch, optimistic updates).
  • Use — Client components: typical pattern is useBffFetchClient inside the query queryFn; tune staleTime and refetch-on-focus as needed.
  • InvalidatequeryClient.invalidateQueries({ queryKey: [...] }) after mutations or when server state may have changed.
  • Avoid — Treating cached values as authoritative for totals, stock, pricing, or permissions without a fresh BFF read.

BFF HTTP cache (Cache-Control / ETag)

  • Role — Browsers and CDNs cache JSON/API responses from Nest.
  • Use — Public or shared responses; optional ETag / Last-Modified for conditional requests.
  • Configure — e.g. Cache-Control: public, s-maxage=…, stale-while-revalidate=… where safe.
  • Avoid — Private or cookie-scoped endpoints: no-store.
  • Note — Next’s server fetch Data Cache does not follow these headers for its own semantics.

NestJS in-process cache (CacheModule / interceptors)

  • Role — Memory or Redis-backed cache inside the BFF.
  • Use — Expensive upstream calls with keyable, safe responses.
  • Invalidate — TTL and/or explicit key eviction (@CacheKey, store APIs).
  • Ops — Multiple BFF instances need a shared store (e.g. Redis) or caches diverge per replica.

CDN / edge

  • Role — Edge caching from response headers (s-maxage, stale-while-revalidate, Vary).
  • Use — Public HTML and APIs in front of Next and/or the BFF.
  • Note — Still separate from the Next.js Data Cache.

Static assets (public/, next/image, build chunks)

  • Role — Long-lived hashed assets.
  • Use — Images, fonts, JS/CSS chunks: usually immutable with long max-age (e.g. one year).

Back to Advanced topics