Hydrogen and Oxygen provide built-in caching to speed up Hydrogen storefronts. The caching API is based on the web-standard [`Cache-Control` API](#cache-control-api).
By default, Hydrogen automatically caches [Storefront API](/docs/api/storefront) data when using Hydrogen’s built-in API client. You can customize or disable caching behavior for every request. You can optionally extend Hydrogen’s built-in utilities to [cache data from third-party APIs](/docs/storefronts/headless/hydrogen/caching/third-party).
Customer Account API data is never cached, because it’s personalized for each user.
## Caching strategies
Hydrogen includes recommended caching strategies to help you determine which cache control header to set. The following table lists the available caching strategies and their associated cache control headers and cache durations:
| Caching strategy | Cache control header | Cache duration |
| ---------------- | ---------------------------------------------------- | -------------- |
| `CacheShort()` | `public, max-age=1, stale-while-revalidate=9` | 10 seconds |
| `CacheLong()` | `public, max-age=3600, stale-while-revalidate=82800` | 1 day |
| `CacheNone()` | `no-store` | No cache |
| `CacheCustom()` | Define your own cache control header | Custom |
### Default caching strategy
By default, each sub-request applies a strategy with the following cache options, which revalidates data after one second and caches it for up to one day:
## Subrequest caching
You can configure the caching strategy for Storefront API data by passing a `cache` option with your query.
The following simplified example shows a component that displays product titles. Because titles don't change often, it caches the data using the `CacheLong()` strategy.
## Custom caching strategies
If you don't want to use the [caching strategies](#caching-strategies) built into Hydrogen, then you can create your own with the `CacheCustom()` function. This function accepts options compatible with the [Cache-Control API](#cache-control-api).
The following strategy directs clients to revalidate the cached data when it’s no longer fresh, not to transform the data, and to consider it fresh for a maximum of 30 seconds:
## Cache-Control API
Hydrogen and Oxygen caching strategies are compatible with the HTTP Header [`Cache-Control` API](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control), with a small number of [exceptions](#cache-control-api-exceptions).
The following options are available when creating a custom caching strategy with `CacheCustom()`:
Option | Type | Description
--- | --- | ---
`mode` | String | One or more comma-separated directives for how caches should handle response data. Accepts `public`, `private`, `no-store`, `must-revalidate`, and `no-transform`.
`maxAge` | Number | The length of time, in seconds, to cache the response.
`staleWhileRevalidate` | Number | The length of time, in seconds, to serve a stale response while fetching a fresh one in the background.
`sMaxAge` | Number | The length of time, in seconds, that proxies or CDNs can store the response.
`staleIfError` | Number | The length of time, in seconds, for the browser to serve a cached response instead when it receives a 5xx error.
Note that`staleIfError` is ignored when caching sub-requests. Instead, use `staleWhileRevalidate` to return stale data if errors are thrown during the revalidation period.
### Cache-Control API exceptions
The `no-cache` directive isn't supported by Oxygen because it instructs the browser not to use the cached data until the server returns a `304 (Not Modified)` status from server. However, Oxygen doesn't return the `304` response status code, so this directive has no effect.