-
Notifications
You must be signed in to change notification settings - Fork 33
Description
- Accepted Date: 2025-03-19
- Reference Issues/Discussions: Route caching #1131 Setting page caching for SSR #181
- Author: @ascorbic @matthewp
- Champion(s): @ascorbic
- Implementation PR:
Astro route caching
Summary
Introduce a platform-agnostic route caching API for Astro SSR pages. This feature enables developers to declaratively define caching rules per route and dynamically override them in middleware or API handlers. It provides a consistent API across Node.js, Vercel, Netlify, Cloudflare, and other deployment targets, ensuring efficient caching while allowing cache invalidation by path or tag when supported. Where possible it will be implemented using CDN caches, but with fallback implemntations where this isn't supported.
Background & Motivation
Currently, caching in Astro SSR requires manually setting Cache-Control
or CDN-Cache-Control
headers, which vary per platform and is not ergonomic. Many modern frameworks offer built-in support for SSR caching strategies, allowing pages to be served efficiently while reducing function invocations and improving performance.
Astro's current lack of a unified caching API means that users must implement custom caching solutions per deployment target, leading to unnecessary complexity. This proposal introduces a framework-level abstraction for caching that integrates seamlessly with Astro’s adapter system, providing an intuitive DX while using platform-specific caching mechanisms where available.
Goals
- Provide a platform-agnostic caching API for Astro SSR routes and server islands.
- Support TTL, stale-while-revalidate (SWR), and ETag-based caching.
- Cache in the CDN where possible, using HTTP cache or
CacheStorage
. - Allow declarative caching definitions in config, with overrides in Astro pages and server islands.
- Enable imperative cache invalidation via by path and tag for fine-grained control.
- Use platform-specific caching mechanisms (CDN, edge cache, etc.) via Astro adapters where available.
- Maintain a consistent API and DX across deployment targets.
Non-goals
- Persistent cache storage in core. This is delegated to the CDN.
fetch
cache. This is for responses only.- Page fragment cache, except for server islands. This is designed for caching complete responses.
- Browser cache handling, except for setting etag and respecting conditional requests.
- Cache rules for prerendered pages.
Example
Declarative API
Cache rules can be declared via route patterns in config:
// astro.config.mjs
export default {
cache: {
routes: {
'/': { maxAge: 0, swr: 60 },
'/blog/**': { maxAge: 300 },
'/api/**': { maxAge: 600 },
}
}
};
They can be overridden in an Astro page or island's frontmatter:
---
Astro.cache({
maxAge: 300, // Cache for 5 minutes
swr: 3600, // Allow stale content for 1 hour while revalidating. In seconds or boolean. Default `true`, meaning 1 hour.
tags: ['blog', 'blog:1'], // Optional cache tags for invalidation
});
---
<html>…</html>
Invalidation
Helper functions allow cache invalidation where the adapter supports it:
// In an API handler or webhook:
export const POST: APIRoute = ({ cache }: APIContext) => {
cache.invalidate({
path: '/blog/my-article', // Invalidate a single page
tag: ['blog', 'home'] // Invalidate all pages tagged as "blog" or "home"
});
return Response.json({
ok: true,
user: 1,
});
};
This uses adapter hooks under the hood, which call the platform-specific APIs. By providing a unified API, Astro ensures that caching is easy to configure while remaining adaptable to different hosting environments.
Adapter support
Each platform has slightly different levels of support, so would need to declare this via adapter features. For example, some platforms don't support cache tags and some don't support invalidation.
Where possible, adapter support would be implemented with CDN-Cache-Control
headers. The cache
config could allow users to specify the header names, for example.
We would implement an optional lightweight cache for the Node adapter using in-memory LRU, but would recommend using an external proxy or CDN cache.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status