docs
  1. Storefront Application
  2. Technical Foundation
  3. Caching

Caching

The Storefront Application provides a comprehensive caching system that improves performance by reducing server load and response times. The caching layer uses Nitro's built-in storage integration with unstorage to provide a runtime-agnostic persistent layer for both page responses and RPC method results.

Overview

Caching in the Storefront Application operates at two levels:

  • Page caching: Caches rendered page responses to reduce server processing time
  • RPC method caching: Caches results from RPC methods to avoid redundant API calls

By default, the Storefront Application uses HTTP Cache-Control headers to instruct external caching mechanisms (browsers, proxies, and CDNs) to cache rendered page responses. This approach reduces memory requirements while maintaining fast content delivery. The application also provides built-in caching for RPC method results, which helps minimize calls to the SCAYLE Storefront API.

How it works

Page Caching

The Storefront Application uses Nuxt's route rules to configure caching behavior per route. The caching strategy depends on your hosting solution:

  • Storefront Hosting: When deployed to Storefront Hosting, page caching is handled by Cloudflare's global cache. The application uses HTTP Cache-Control headers to instruct Cloudflare to cache responses, reducing server load and improving response times. The application itself does not store cached page responses.
  • Other hosting solutions: When deployed to other platforms (such as self-hosted infrastructure with Redis), you can enable in-application caching. This stores rendered page responses in your configured storage backend (e.g., Redis), allowing the application to serve cached responses directly.

By default, the Storefront Application uses HTTP cache headers only (headersOnly: true), which is the recommended configuration for Storefront Hosting. Most pages are cached for 10 minutes, and the application relies on external caches (browsers, proxies, and CDNs) to store and serve cached content, which reduces the application's memory footprint.

User-specific routes such as /basket, /wishlist, /checkout, /signin, and /account/** are excluded from caching to ensure data accuracy and provide personalized experiences.

RPC Method Caching

RPC methods can use the context.cached() function from the RPC Context to cache their results. The cached property is a utility function available on the RpcContext object that wraps functions with caching behavior.

When an RPC method uses caching, the Storefront SDK checks the cache before executing the function. If a cached result exists and is still valid, it returns the cached value. Otherwise, it executes the function, stores the result in the cache, and returns it.

The cache automatically generates cache keys based on function arguments, or you can specify explicit cache keys. Cache entries can have a time-to-live (TTL) to control how long they remain valid. This is particularly useful for caching expensive operations like API calls to the SCAYLE Storefront API, reducing server load and improving response times.

Technical Architecture

The Storefront Application's caching system is built on top of Nitro's caching layer, which integrates with unstorage to provide a unified storage API. The system supports multiple storage backends, including in-memory storage, Redis, and other persistent stores.

Storage Configuration

For detailed information about storage configuration and drivers, see the Storage documentation.

The application configures two storage namespaces:

  • storefront-session: Stores user session data (authentication, basket state, etc.)
  • storefront-cache: Stores cached API responses and other cacheable data

The storage configuration adapts based on the deployment environment:

  • Storefront Hosting (recommended): Uses SCAYLE KV driver with brotli compression for both session and cache storage. For more details, see the Storefront Hosting migration guide.
  • Vercel: Uses Vercel KV (Redis) for both session and cache storage with gzip compression
  • Other platforms: Uses SCAYLE KV driver, an optimized Redis driver, with brotli compression for better compression ratios.

The storage configuration is set up in server/plugins/storageConfig.ts:

Hybrid Rendering

The Storefront Application uses hybrid rendering, which allows different caching rules per route. Nuxt intelligently chooses between Server-Side Rendering (SSR) and Client-Side Rendering (CSR) based on the route's requirements. This approach optimizes the balance between server-side rendering for initial page loads and client-side rendering for subsequent interactions.

Implementation

Page Caching Configuration

Page caching is configured using routeRules in nuxt.config.ts. The default configuration of the Storefront Application is optimized for Storefront Hosting, which uses Cloudflare for page caching.

The configuration adapts based on your routing strategy:

  • Domain-based routing (SHOP_SELECTOR_MODE === 'domain'): Uses simple route patterns without locale prefixes. Each domain handles its own locale.
  • Path-based routing (SHOP_SELECTOR_MODE === 'path' or 'path_or_default'): Generates locale-specific route rules for each configured locale (e.g., /en-US/**, /de-DE/**). The locales.reduce() function dynamically creates rules for each locale while maintaining the same caching logic per locale path.

The headersOnly: true option ensures that the application only applies Cache-Control headers to responses. When deployed to Storefront Hosting, Cloudflare uses these headers to cache responses at the edge, reducing server load and improving response times. The application itself does not store cached page responses in this configuration.

Enable In-Application Caching

If you are deploying to Storefront Hosting, do not enable in-application caching. Storefront Hosting uses Cloudflare for page caching, and the default headersOnly: true configuration is required.

To enable in-application caching for rendered page responses, remove the headersOnly: true option from your route rules. This is useful if you host the Storefront Application on other platforms (such as self-hosted infrastructure with Redis) and want the application to store cached responses:

When in-application caching is enabled, the Storefront Application stores rendered page responses in your configured storage backend (e.g., Redis). You can configure additional options:

  • group: 'ssr' and name: 'page': Add ssr:page to the cache key prefix for easier identification
  • varies: ['host', 'x-forwarded-host']: Append host header values to cache keys for domain-based routing
  • base: 'storefront-cache': Use the configured storage backend instead of in-memory cache. Important: In-memory cache should never be used for production deployments as it doesn't persist across server restarts and can cause memory issues.

Using Cache in RPC Methods

The RpcContext object includes a cached function that wraps functions with caching behavior. This function is available to all RPC methods through the context parameter. For more information about the RPC Context and its properties, see the RPC methods documentation.

The cached() function takes a function as its first argument and cache options as its second argument:

Cache Options

The cached() function accepts the following options:

OptionDescription
cacheKeyExplicit cache key. If provided, the function uses this key instead of generating one.
cacheKeyPrefixPrefix for automatically generated cache keys. The generated key is cacheKeyPrefix concatenated with a hash of the function arguments.
ttlTime-to-live in seconds. Defines how long a cache entry remains valid.
timeoutTimeout in milliseconds for cache requests. If the cache doesn't return a result within this period, the function executes instead. Defaults to 500ms.

Configuration

For more information about Storefront configuration options, see the Configuration documentation.

Disabling Cache

Internal Cache for RPC Methods

Disabling internal caching is not recommended, as it drastically increases load on API endpoints by removing the caching layer for RPC method results. Only disable caching if you have a specific requirement that cannot be met with cached responses.

Disable the internal cache used by context.cached():

  • At build-time: Set cache.enabled to false in nuxt.config.ts:
  • At runtime: Set the NUXT_STOREFRONT_CACHE_ENABLED environment variable to false.

SSR Cache (Page Caching)

Disable SSR page caching:

  • At runtime: Set the PAGE_CACHE_DISABLED environment variable to true.

Clear Cache

The Storefront Application provides API endpoints to clear the cache:

Purge All Cache

Clear the entire cache by sending a POST request to /api/purge/all:

Purge by Tags

Clear cache entries by tags by sending a POST request to /api/purge/tags with an array of tags in the request body:

Cache Authentication

To protect cache clearing endpoints, configure basic authentication in nuxt.config.ts:

Once configured, all requests to cache clearing endpoints must include an Authorization header with base64-encoded credentials:

Best Practices

Page Caching

  • Storefront Hosting: Always use headersOnly: true to leverage Cloudflare's global cache. Do not enable in-application caching when deployed to Storefront Hosting.
  • Other hosting solutions: Use headersOnly: true when using external CDNs to reduce memory usage, or enable in-application caching if you have a storage backend like Redis configured.
  • Never use in-memory cache in production: Always configure a persistent storage backend (e.g., Redis, SCAYLE KV) for production deployments. In-memory cache doesn't persist across server restarts and can cause memory issues.
  • Exclude user-specific routes from caching to ensure data accuracy (e.g., /basket, /wishlist, /checkout, /signin, /account/**, /api/**)
  • Configure appropriate maxAge values based on content update frequency
  • For path-based routing: Ensure route rules are properly configured for each locale path (the application handles this automatically via locales.reduce())
  • For domain-based routing: Use varies: ['host', 'x-forwarded-host'] in cache configuration to ensure correct cache keys per domain

RPC Method Caching

  • Keep internal caching enabled: Disabling RPC method caching drastically increases load on API endpoints. Only disable if you have a specific requirement that cannot be met with cached responses.
  • Use descriptive cacheKeyPrefix values to identify cache entries easily (e.g., getById-product-${id})
  • Set appropriate TTL values based on data update frequency (e.g., 5 minutes for product data, longer for static configuration)
  • Cache expensive operations like API calls to the SCAYLE Storefront API
  • Avoid caching user-specific data unless the cache key includes user identifiers
  • Use cacheKeyPrefix with dynamic values (like IDs) to ensure proper cache key generation

Storage Configuration

  • Storefront Hosting (recommended): Uses SCAYLE KV driver with brotli compression automatically configured
  • Vercel: Uses Vercel KV with gzip compression
  • Other platforms: Configure SCAYLE KV driver or Redis with brotli compression for better compression ratios
  • Always configure storage mounts in server/plugins/storageConfig.ts for proper cache and session storage

Performance Considerations

  • Monitor cache hit rates to optimize cache configuration and TTL values
  • Use compression (brotli or gzip) for cache storage to reduce memory usage
  • Configure cache timeouts to prevent blocking requests when cache is slow (default: 500ms)
  • Test cache behavior in development to ensure correct invalidation
  • Use headersOnly: true when possible to offload caching to external CDNs and reduce application memory usage

Troubleshooting

Issue: Cached data is stale

Applies to: Page caching and RPC method caching

Possible causes:

  • TTL value is too high
  • Cache is not being cleared when data updates
  • External cache (CDN) is serving stale content (page caching only)

Solution:

  1. Reduce TTL values for frequently updated data
  2. Implement cache invalidation when data changes
  3. Clear external caches or reduce their cache duration (page caching only)

Prevention:

Set appropriate TTL values and implement cache invalidation strategies.

Issue: Cache is not working

Applies to: Page caching and RPC method caching

Possible causes:

  • Caching is disabled via environment variable or configuration
  • Cache storage is not properly configured
  • Route rules are excluding the route from caching (page caching only)

Solution:

  1. Verify NUXT_STOREFRONT_CACHE_ENABLED is not set to false (RPC method caching)
  2. Check storage configuration in server/plugins/storageConfig.ts
  3. Review route rules in nuxt.config.ts to ensure routes are not excluded (page caching only)

Prevention:

Test caching behavior in development and verify configuration.

Issue: Memory usage is high

Applies to: Page caching (primarily)

Possible causes:

  • In-application caching is enabled without external CDN-related configuration
  • Cache entries are not expiring
  • Too many cache entries are being stored

Solution:

  1. Enable headersOnly: true to use external caches
  2. Reduce TTL values to expire entries faster
  3. Implement cache size limits or eviction policies

Prevention:

Use headersOnly: true when possible and configure appropriate TTL values.