Joint session with Vercel: How to build intelligent storefronts (May 15th)

Sanity blog updates delayed 5-10 minutes on Vercel production

11 repliesLast updated: Nov 29, 2025

Hello. I believe I have some sort of cache problem. I have a blog on Sanity and when I create or edit blog posts I can see the update instantly when I publish it on local but it takes close to 5-10min to appear on production. Ultimately it does appear but I'm wondering why this is happening.My blog is on Nextjs, hosted on Vercel.
AI Update

This is a classic caching issue when using Next.js with Sanity! The 5-10 minute delay you're experiencing is likely due to multiple caching layers working together. Let me break down what's happening and how to fix it.

Why This Happens

You're dealing with two separate caches:

When you publish content, it updates in Sanity's Content Lake immediately (which is why you see it locally if you're querying without the CDN), but the cached versions take time to update.

The Solution: On-Demand Revalidation with Webhooks

The best approach is to set up on-demand revalidation using Sanity webhooks. This tells Vercel to immediately rebuild affected pages when you publish content. Here's how to set it up:

Step 1: Create a Revalidation API Route

In your Next.js app, create an API route. For the App Router, create app/api/revalidate/route.ts:

import { revalidateTag } from 'next/cache'
import { type NextRequest, NextResponse } from 'next/server'
import { parseBody } from 'next-sanity/webhook'

export async function POST(req: NextRequest) {
  try {
    const { body, isValidSignature } = await parseBody(
      req,
      process.env.SANITY_REVALIDATE_SECRET
    )
    
    if (!isValidSignature) {
      return new Response('Invalid signature', { status: 401 })
    }

    if (!body?._type) {
      return new Response('Bad Request', { status: 400 })
    }

    // Revalidate specific tags based on document type
    revalidateTag(body._type)
    
    return NextResponse.json({
      status: 200,
      revalidated: true,
      now: Date.now()
    })
  } catch (err) {
    console.error(err)
    return new Response('Internal Server Error', { status: 500 })
  }
}

For the Pages Router, create pages/api/revalidate.ts:

import type { NextApiRequest, NextApiResponse } from 'next'
import { parseBody } from 'next-sanity/webhook'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    const { body, isValidSignature } = await parseBody(
      req,
      process.env.SANITY_REVALIDATE_SECRET
    )
    
    if (!isValidSignature) {
      return res.status(401).json({ message: 'Invalid signature' })
    }

    // Revalidate the path for this document
    await res.revalidate('/blog') // Adjust to your blog path
    
    return res.json({ revalidated: true })
  } catch (err) {
    return res.status(500).json({ message: 'Error revalidating' })
  }
}

Step 2: Set Up a Sanity Webhook

Step 3: Disable Sanity CDN for Production Builds

In your Sanity client configuration, set useCdn: false to ensure you're getting fresh data during builds. The Sanity CDN and Next.js ISR can work at cross-purposes:

import { createClient } from 'next-sanity'

export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: false, // Disable CDN for fresh data
})

Modern Alternative: Sanity Functions

If you're on a Growth plan or higher, consider using Sanity Functions instead of webhooks. Functions run serverless code directly in Sanity when content changes, eliminating the need for external webhooks entirely. This is the modern, recommended approach for handling content events, as it provides better security, automatic scaling, and native integration with Sanity.

Quick Fix: Time-Based Revalidation

If you need a simpler solution right now, you can use time-based ISR revalidation in your data fetching:

// App Router with fetch
const posts = await fetch('https://your-project.api.sanity.io/...', {
  next: { revalidate: 60 } // Revalidate every 60 seconds
})

// Or with sanityFetch
const posts = await sanityFetch({
  query: POSTS_QUERY,
  revalidate: 60, // Revalidate every 60 seconds
})

This won't give you instant updates, but it'll reduce the delay from 5-10 minutes to 1 minute.

The on-demand revalidation approach is definitely the way to go for production sites where content authors expect immediate updates after publishing!

Show original thread
11 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions