Skip to content

astro

Astro Cache Provider API

Astro

Astro Cache Provider API

Astro Cache Provider API

Astro Cache Provider API allows you to configure and manage route caching behavior. This API includes built-in support for an in-memory cache provider and the ability to create custom providers for various caching strategies and runtimes.

What is a cache provider?

Cache behavior is determined by the configured cache provider. Providers fall into two categories:

CDN providers

CDN providers translate cache directives into response headers (e.g. CDN-Cache-Control, Cache-Tag) and rely on a CDN or reverse proxy to handle caching. These internal headers are stripped before the response reaches the client.

A CDN provider implements setHeaders() to produce the appropriate headers.

Runtime providers

Runtime providers implement onRequest() to intercept requests and cache responses in-process. They add an X-Astro-Cache response header for observability:

  • HIT: response served from cache
  • MISS: response rendered fresh and stored in cache
  • STALE: stale response served while revalidating in the background

Built-in memory cache provider

Astro includes a built-in in-memory LRU runtime cache provider suitable for single-instance deployments. Import memoryCache() from astro/config:

memoryCache() options

Type: { max?: number; query?: object }
Default: { max: 1000 }

Configures the in-memory cache provider.

max

Type: number
Default: 1000

Defines the maximum number of entries to keep in cache. When the cache exceeds this limit, the least recently used entry is evicted.

query

Type: { sort?: boolean; include?: string[]; exclude?: string[]; }

Controls how query parameters are handled in cache keys.

query.sort

Type: boolean
Default: true

Determines whether query parameters should be sorted alphabetically. This is useful when parameter order is significant and to ensure that their order does not affect the cache key.

Set to false to disable sorting and cache URLs with different query parameter orders separately.

query.exclude

Type: string[]
Default: ['utm_*', 'fbclid', 'gclid', 'gbraid', 'wbraid', 'dclid', 'msclkid', 'twclid', 'li_fat_id', 'mc_cid', 'mc_eid', '_ga', '_gl', '_hsenc', '_hsmi', '_ke', 'oly_anon_id', 'oly_enc_id', 'rb_clickid', 's_cid', 'vero_id', 'wickedid', 'yclid', '__s', 'ref']

Lists the query parameters to exclude from the cache key. This supports glob wildcards (e.g. "utm_*") and, by default, excludes common tracking and analytics parameters.

Set to [] to include all query parameters in the cache key:

memoryCache({
  query: { exclude: [] },
});

An error is thrown if used together with include.

query.include

Type: string[]

Lists the query parameter names to include in the cache key. When set, all other parameters are ignored, including default tracking parameter exclusions.

The following example only uses page and sort parameters in the cache key, ignoring all others:

memoryCache({
  query: { include: ['page', 'sort'] },
});

An error is thrown if used together with exclude.

Cache key behavior

The memory provider automatically normalizes cache keys for better hit rates:

  • Query parameter sorting: Parameters are sorted alphabetically, so /page?b=2&a=1 and /page?a=1&b=2 resolve to the same cache entry.
  • Tracking parameter exclusion: Common analytics and tracking parameters (e.g. utm_source, fbclid, gclid) are excluded from the cache key by default. This prevents cache fragmentation from marketing links without affecting your page content.
  • Vary header support: When a response includes a Vary header, the memory provider uses the specified request header values to create separate cache entries for each variant. For example, a response with Vary: Accept-Language will cache different versions for different languages.

:::note The Cookie header is always ignored for Vary-based cache keying because it has extremely high cardinality (every user typically has different cookies), making it effectively uncacheable. :::

Writing a custom cache provider

A cache provider has two parts:

  1. The runtime module — A file that default-exports a CacheProviderFactory function. This module is bundled into your SSR output, so it must be runtime-agnostic: avoid Node.js built-in modules (e.g. node:fs, node:path) unless your target runtime supports them.

  2. The config helper — A function exported for users to call in astro.config.mjs. It returns a CacheProviderConfig object that tells Astro where to find the runtime module and what options to pass it. This is the same pattern used by the built-in memoryCache() provider.

The following example shows a config helper that accepts typed options and points to a runtime module:


interface MyProviderOptions {
  apiKey: string;
  region?: string;
}


}

The config helper is then called in the Astro config:


The runtime module default-exports a factory that receives the serialized config and returns a CacheProvider:


const factory: CacheProviderFactory = (config) => {
  return {
    name: 'my-cache-provider',

    // CDN-style: translate cache options into response headers
    setHeaders(options) {
      const headers = new Headers();
      if (options.maxAge !== undefined) {
        let value = `max-age=${options.maxAge}`;
        if (options.swr !== undefined) {
          value += `, stale-while-revalidate=${options.swr}`;
        }
        headers.set('CDN-Cache-Control', value);
      }
      if (options.tags?.length) {
        headers.set('Cache-Tag', options.tags.join(','));
      }
      return headers;
    },

    // Runtime-style: intercept requests (optional)
    async onRequest(context, next) {
      // Check cache, call next(), store response...
      return next();
    },

    // Handle invalidation requests
    async invalidate(options) {
      // Purge by tags or path...
    },
  };
};

When writing a CDN provider, Astro provides shared utilities for building cache-control headers and path-based invalidation tags.

Cache provider utilities

Astro exports shared helpers for CDN provider authors from astro/cache/provider-utils. These are the same helpers used by the first-party Netlify, Vercel, and Cloudflare providers.

buildCacheControlDirectives()

Type: (options: CacheOptions, extraDirectives?: string[]) => string | undefined

Builds a cache-control directive string (e.g. "public, max-age=300, stale-while-revalidate=60") from CacheOptions, without a header name so each provider can apply its own (such as Netlify-CDN-Cache-Control or Cloudflare-CDN-Cache-Control). Pass extraDirectives to prepend platform directives such as public or durable. Returns undefined when there are no caching directives.

pathTag()

Type: (path: string) => string

Generates a cache tag for a given path (astro-path:{path}). Used to support invalidate({ path }) on platforms that only offer tag-based purging.

setConditionalHeaders()

Type: (headers: Headers, options: CacheOptions) => void

Sets Last-Modified and ETag headers on a Headers object from the corresponding CacheOptions values.

collectInvalidationTags()

Type: (options: InvalidateOptions) => string[]

Collects all tags needed to invalidate the given options, including the path tag when options.path is set. Used by providers that implement path invalidation via tags rather than native path purge.

normalizeTags()

Type: (tags: string | string[] | undefined) => string[]

Normalizes a tag value to a flat string array.

Cache provider types reference

The following types can be imported from the astro module:

CacheOptions

Describes the options passed to a cache provider.

Learn how to use cache options to control caching behavior.

CacheOptions.maxAge

Type: number

Defines the time in seconds the response is considered fresh.

CacheOptions.swr

Type: number

Specifies the stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.

CacheOptions.tags

Type: string[]

A list of cache tags for targeted invalidation. Tags accumulate across multiple cache.set() calls.

CacheOptions.lastModified

Type: Date

Indicates the most recent modification date. When multiple calls to cache.set() provide lastModified, the most recent call takes precedence.

CacheOptions.etag

Type: string

Specifies the entity tag for conditional requests.

CacheProvider

Describes a provider used for caching. This requires the name and invalidate() properties and accepts optional properties.

CacheProvider.name

Type: string

A unique name for the provider, used in logs and for identification.

CacheProvider.setHeaders()

Type: (options: CacheOptions, request: Request) => Headers

Translates cache options into response headers. This is called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.

The incoming request is passed as a second argument so a provider can read the URL or request headers. This can be useful to auto-tag responses with their pathname for path-based invalidation.

CacheProvider.onRequest()

Type: (context: { request: Request; url: URL; waitUntil?: (promise: Promise<unknown>) => void }, next: MiddlewareNext) => Promise<Response>

Intercepts requests to implement runtime caching. The context includes a waitUntil() function (when available in the runtime) for background work such as stale-while-revalidate.

CacheProvider.invalidate()

Type: (options: InvalidateOptions) => Promise<void>

Handles purge requests by tag or path.

CacheProviderConfig

Type: { entrypoint: string | URL; config?: Record<string, any> }

The configuration object passed to cache.provider. Use a helper function (e.g. memoryCache()) for type-safe configuration.

CacheProviderFactory

Type: (config: Record<string, any> | undefined) => CacheProvider

The factory function type. Receives the provider's serializable config object from the Astro config.

InvalidateOptions

Describes the options passed to the provider's invalidate() method.

InvalidateOptions.path

Type: string

Exact path to invalidate. No glob or wildcard support.

InvalidateOptions.tags

Type: string | string[]

Tag or tags to invalidate. All entries with matching tags are purged.