revalidateTag vs updateTag
Medium · Caching
Cached data can be labelled with **tags**, e.g. fetch(url, { next: { tags: ["posts"] } }) or cacheTag("posts") inside "use cache". After a change you invalidate a tag instead of a URL. Next.js 16 has two ways:
- revalidateTag("posts", "max"): marks the entries as **stale** (stale-while-revalidate). The next visitor still gets the old data instantly while Next.js refreshes it in the background; later visitors get the new data. Great for content where a few seconds of delay is fine.
- updateTag("posts") (Server Actions only): **expires** the entries immediately. The next read waits for fresh data, so the user who just saved something sees their own change ("read-your-writes").
Implement a simplified TagCache. The constructor receives load(key), which reads the current value from the database.
- get(key, tags) returns { value, status }:
- No entry (never loaded or expired): load it, store it with tags, status "MISS".
- Fresh entry: return the cached value, status "HIT" (even if the database changed).
- Stale entry: return the **old** value with status "STALE", then replace the entry with a freshly loaded one (with the new tags). Real Next.js refreshes in the background; here do it right away.
- revalidateTag(tag): mark every entry that has this tag as stale.
- updateTag(tag): remove every entry that has this tag.
The driver runCache(ops) is already written. It logs "<key> = <value> (<status>)" for every get.