Skip to content

Conversation

@ascorbic
Copy link
Contributor

@ascorbic ascorbic commented Oct 15, 2025

Summary

A platform-agnostic route caching API for Astro SSR pages that enables declarative cache control using web standards.

Examples

Basic route caching

---
// src/pages/products/[id].astro
import { getEntry } from 'astro:content';
const product = await getEntry('products', Astro.params.id);
Astro.cache({
  lastModified: product.updatedAt,
  maxAge: 300,  // Cache for 5 minutes
  swr: 3600,    // Stale-while-revalidate for 1 hour
  tags: ['products', `product:${product.id}`]
});
---
<h1>{product.data.name}</h1>
<p>{product.data.description}</p>

Automatic dependency tracking

// src/pages/api/revalidate.ts
import { getLiveEntry } from "astro:content";

export const POST: APIRoute = async ({ cache, request }) => {
  const { id } = await request.json();
  const { entry } = await getLiveEntry("products", id);

  // Invalidate all pages that depend on this entry
  cache.invalidate(entry);

  return Response.json({ ok: true });
};

Links

@ascorbic ascorbic mentioned this pull request Oct 15, 2025
Added cache configuration for routes in astro.config.ts and updated cache invalidation tag in webhook API.
@wildfiremedia
Copy link

I’d like to see a summary of the total cache along with a list of tags, so we can get an idea of what’s being cached or invalidated and catch any tags that might have been missed which allows us to easily debug.

@florian-lefebvre
Copy link
Member

I'm not sure that's something for Astro to provide, feels like maybe it should be achievable through the driver platform (eg. cloudflare)?

@wildfiremedia
Copy link

wildfiremedia commented Oct 21, 2025

Exclusively for self-hosted servers, these metrics (memory, SWR settings, etc.) are provided in JSON format. I think they could be useful for storefronts that need to cache product listings.

Other ideas, can it cache payload in gzipped or brotli? Thinking by 50% or more is worth saving and reduce latency.

@stipsan
Copy link

stipsan commented Nov 14, 2025

From the perspective of Sanity I think we'd like to automatically define cache tags since our backend provides them, regardless of how customers define their GROQ queries and how the data is fetched, it's fairly dynamic.
But we wouldn't want to define maxAge or swr automatically.

For us if we can define a live loader that could call Astro.cacheTag(...tags: string[]) and have it hoist up/merge with the userland Astro.cache() call that would be ideal.
Since we allow resolving references, which is similar to a db join, even getting a single document entry might have linked data that have multiple cache tag.

A blog post could be resolving an author reference. If the author reference is edited it should invalidate all post entries that use it.
For that to work without too much wiring we'd need to define all the cache tags that can be used for invalidation on both the get entry and on the collection levels.

Since customers often fetch data from other sources than ours we can't make any assumptions on their maxAge and swr ideal settings.

For next.js we're able to do this by calling cacheTag, and changing the revalidate setting on cacheLife. Userland can override these settings by having the callsite use shorter revaldiate times, as well as different settings for stale and expire. I'd like for Astro users to have the same, simple, API surface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants