Help articles

Next.js 16 and SanityLive: avoiding request overages

Upgrading to Next.js 16 with SanityLive on next-sanity v12 can multiply prefetch requests and ISR writes, leading to Sanity API overages. What to expect and how next-sanity v13 resolves it.

This issue is resolved in next-sanity v13

If you're using SanityLive in a Next.js app on next-sanity v12, upgrading to Next.js 16 can cause a large increase in requests and ISR writes compared to Next.js 15. That increase can drive up Sanity API usage and Vercel ISR costs. next-sanity v13 changes the default cache invalidation behavior to avoid this. This article covers what to expect, what changed in v13, and how to reduce the load if you're still on v12.

This applies if: you're running a Next.js App Router app, using next-sanity's defineLive and <SanityLive>, and you're upgrading from Next.js 15 to 16 on next-sanity v12 (or have already upgraded).

What to expect

On next-sanity v12 with Next.js 16 and <SanityLive>, the default <Link> prefetch behavior combined with how <SanityLive> calls revalidateTag produces a cascade: each prefetch fires more requests than on v15, a live event invalidates the client-side cache, prefetches run again, and routes that match the revalidated tag re-fetch and write to ISR.

In production we've seen an average 4x increase in request load from the same app after upgrading. Worst cases (marketing and docs sites with many segments) are 7–10x or more.

How to tell if this is affecting you

  • Your app is on Next.js 16 with <SanityLive> in use.
  • Sanity API request counts jumped 4x or more after the upgrade, with no comparable change in traffic.
  • Vercel ISR writes spiked on routes that consume Sanity content.
  • Browser devtools show multiple ?rsc requests fired for each <Link> prefetch.

Safest way to run SanityLive on Next.js 16 with next-sanity v12

If you can't upgrade to next-sanity v13 yet and you're not using cache components, this is the safest setup on v12:

  • Upgrade to at least Next.js 16.2 and enable experimental.prefetchInlining.
  • Keep using sanityFetch from defineLive in production, but don't render <SanityLive> unless Presentation Tool or visual editing is active.
  • Use a sync tag function and set up an /api/expire-tags handler in your Next.js app that calls revalidateTag(tag, "max"). Then call this route from the sync tag function.
  • When you do render <SanityLive> (per step 2, for Presentation Tool or visual editing), render it only in draft mode and override revalidateSyncTags so it no longer calls revalidateTag(tag, { expire: 0 }).

The refreshAction implementation must live in a file marked 'use client' (not 'use server') and return 'refresh'. That tells <SanityLive> to call router.refresh() for you, which triggers a single GET that live-updates the page.

Use cache components

next-sanity v13 supports defineLive with Next.js Cache Components (cacheComponents: true). It isn't a drop-in change: Sanity Live with Next.js Cache Components covers the setup steps and the migration path from an existing Sanity Live setup.

Why next-sanity v12 on Next.js 16 causes extra requests

On next-sanity v12, this combination is supported but carries overage risk. The default prefetch behavior on <Link> tags changed in v16 (see Next.js's "Incremental prefetching"). Combined with <SanityLive> calling revalidateTag(tag, { expire: 0 }), the result is:

  • Each <Link> prefetch fires many more requests than in v15. On sanity.io we observed 2 requests with ?rsc on v15 versus 7 on v16.
  • <SanityLive> receives a live event and calls revalidateTag(tag, { expire: 0 }). That server action nukes the Next.js client-side cache (router.refresh() has the same effect).
  • Clearing the client cache empties the prefetch cache. Next.js sees the visible Link tags and prefetches them all again.
  • If any of those prefetches hit a route tagged with the revalidated tag, Next.js responds CACHE: REVALIDATED (its internal signal that a tagged route was re-rendered), which performs a data fetch (counts toward Sanity API usage) and triggers an ISR write (billable on Vercel).

Next.js's core team has confirmed the prefetch request change. The CACHE: REVALIDATED behavior on prefetch links is still under investigation.

Resolution in next-sanity v13

next-sanity v13.0.0 shipped on May 21, 2026. It changes the default cache invalidation behavior on <SanityLive> and adds support for Next.js Cache Components. Upgrading from v12 is a breaking change: the v12 to v13 migration guide lists every change, including the revalidateSyncTags prop, which is replaced by action.

Related articles

Was this page helpful?