Fetch cache (next.revalidate)

Server-side fetch(url, { next: { revalidate: 10, tags: ["echo-demo"] } }) caches the upstream response for 10 seconds. The OUTER timestamp ticks on every refresh; the inner receivedAt from the cached fetch stays frozen for the freshness window.

Output

Outer (live): 2026-05-03T10:37:19.838Z

Cached receivedAt: 2026-05-03T10:37:19.838Z

Full response JSON
{"method":"GET","path":"/api/echo","query":{"key":"fetch-cache-demo"},"headers":{"user-agent":null,"content-type":null},"body":null,"receivedAt":"2026-05-03T10:37:19.838Z"}

How it works

The fetch polyfill in the V8 host forwards options.next through to __httpFetch, which consults bext_core::cache::fetch_cache::FetchCache before touching the network. On a hit, the cached JSON envelope is returned directly. On a miss, the upstream call runs and the response is stored under hash(url, method, body), indexed by every tag in next.tags.

revalidateTag(tag) from @bext-stack/framework/cache calls __bextRevalidateTag on the host, which walks the tag index and drops every entry tagged with that string. Cross-worker fan-out via the existing PURGE wire frame is a follow-up; today the invalidation is process-local.

Source

import { revalidateTag } from "@bext-stack/framework/cache";

    // Fetch with cache config.
    const r = await fetch("/api/echo?key=demo", {
        next: { revalidate: 10, tags: ["echo-demo"] },
    });
    const data = await r.json();
    // Elsewhere — invalidate the tagged entries.
    revalidateTag("echo-demo");