Next.js Discord

Discord Forum

cacheLife blocks navigation and prevents Suspense streaming

Unanswered
Standard Chinchilla posted this in #help-forum
Open in Discord
Standard ChinchillaOP
Hey everyone! I'm trying to figure out cacheLife and running into some confusing behavior. Would really appreciate any insights!

I want to cache data for 3 seconds, and here's the behavior I'm going for:

1. First visit: Show my skeleton UI → wait 3 seconds → display data ✨
2. Navigate back within 3 seconds: Show cached data immediately (instant, no loading!)
3. Navigate back after 3 seconds: Cache expired → show skeleton again → fetch fresh data

## The Problem 😅

With revalidate or expire:

- The page completely blocks/freezes for 3 seconds 😢
- DevTools shows "prerendering" during the block
- My Suspense fallback never shows up
- Users just see a blank page instead of my nice skeleton

With just stale:

- Great news: page doesn't block! 🎉
- Bad news: cache never expires... like, ever
- Even after waiting 30+ seconds, it keeps showing old cached data
- Skeleton never appears again

## Here's my code

async function getInsights() {
  // I have this 3-second delay on purpose to see my skeleton UI
  await new Promise(resolve => setTimeout(resolve, 3000));
  return .....
}

export async function Insights() {
  return (
    <Suspense fallback={<InsightsSkeleton />}>
      <InsightsCards />
    </Suspense>
  );
}

async function InsightsCards() {
  'use cache';
  cacheLife({ revalidate: 3 }); // This is where things go wrong
  const insights = await getInsights();
  return <div>{/* render data */}</div>;
}


## What I've tried so far

Option 1: cacheLife({ revalidate: 3 }) or cacheLife({ expire: 3 })
→ Page blocks, no streaming 😔

Option 2: cacheLife({ stale: 3 })
→ No blocking (yay!) but cache never expires (oh no!)


The Suspense boundary works perfectly when I use only "use cache"

Is this the expected behavior? Should revalidate/expire block the page like this?

Would really appreciate any pointers or if someone could help me understand what's going on. Thanks in advance! 🙏

1 Reply

Standard ChinchillaOP
Update / Discovery 🔍

I finally figured out what’s happening — the caching behavior is actually different between development and production builds. 🤬

When I run the app in dev mode (pnpm dev), cacheLife({ expire: 3 }) completely blocks rendering and my Suspense fallback never shows up (the same issue I described above).

But when I build the app (pnpm build && pnpm start), everything works perfectly — exactly as expected! The cache revalidates after 3 seconds, the skeleton appears on expired cache, and the page doesn’t freeze.

Honestly, this difference between dev and production feels like one of the worst parts of the Next.js DX right now. It’s the same kind of frustration I’ve hit with Server Actions too — in dev you can throw custom error messages, but in production those messages get swallowed. Having different behaviors between environments makes debugging way harder than it should be 😩