Next.js Discord

Discord Forum

On demand ISR and stale cache

Answered
Paper wasp posted this in #help-forum
Open in Discord
Paper waspOP
Hi, I'm using Nextjs on vercel and I'm seeing a behavior that I don't understand.

I'm using Next 15 and the app router. My code is the following:

import UiRecipe from "@/components/ui/UiRecipe/UiRecipe";
import { cfImage } from "@/lib/contentful";
import { getRecipe, getRecipes } from "@/lib/recipe";
import { unstable_cache } from "next/cache";

const placeholder = "/placeholders/600x400.png";

export const revalidate = 60;

export async function generateStaticParams() {
  const recipes = await getRecipes();

  return recipes.map((recipe) => ({
    slug: recipe.fields.slug,
  }));
}

export default async function Recipe({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const slug = (await params).slug;

  const getCachedRecipe = unstable_cache(getRecipe, [slug], {
    tags: ["recipes", `recipes-${slug}`],
    revalidate: 60,
  });

  const recipe = await getCachedRecipe(slug);
  const imageSrc =
    cfImage(recipe.fields.image?.fields.file?.url) ?? placeholder;

  return (
    <main>
      <UiRecipe
        name={recipe.fields.title ?? ""}
        image={imageSrc}
        ingredients={recipe.fields.ingredients}
        directions={recipe.fields.directions}
        tags={[]}
      />
    </main>
  );
}


The ISR behavior seems to work properly: every 60 seconds after the cache generation, I get one last stale page which triggers the background regeneration, and if I come back a second after, I get a new page (age between 1 and 10 in the header so I guess its a new one). If my content is updated in between, the stale is not up to date, the new one is. everything works like expected.

however, I have added 2 tags in the unstable_cache fetch, and when I invalidate them using an invalidateTags, the next request is (I guess) SSR'd, it takes around 300+ms, and is directly up to date. I thought I would get a stale and always hit the cache just like the standard ISR. is it the intended behavior ?
Answered by American Crocodile
I was searching for solutions for this problem, and yes it is the intended behaviour.
View full answer

3 Replies

@Paper wasp Hi, I'm using Nextjs on vercel and I'm seeing a behavior that I don't understand. I'm using Next 15 and the app router. My code is the following: ts import UiRecipe from "@/components/ui/UiRecipe/UiRecipe"; import { cfImage } from "@/lib/contentful"; import { getRecipe, getRecipes } from "@/lib/recipe"; import { unstable_cache } from "next/cache"; const placeholder = "/placeholders/600x400.png"; export const revalidate = 60; export async function generateStaticParams() { const recipes = await getRecipes(); return recipes.map((recipe) => ({ slug: recipe.fields.slug, })); } export default async function Recipe({ params, }: { params: Promise<{ slug: string }>; }) { const slug = (await params).slug; const getCachedRecipe = unstable_cache(getRecipe, [slug], { tags: ["recipes", `recipes-${slug}`], revalidate: 60, }); const recipe = await getCachedRecipe(slug); const imageSrc = cfImage(recipe.fields.image?.fields.file?.url) ?? placeholder; return ( <main> <UiRecipe name={recipe.fields.title ?? ""} image={imageSrc} ingredients={recipe.fields.ingredients} directions={recipe.fields.directions} tags={[]} /> </main> ); } The ISR behavior seems to work properly: every 60 seconds after the cache generation, I get one last stale page which triggers the background regeneration, and if I come back a second after, I get a new page (age between 1 and 10 in the header so I guess its a new one). If my content is updated in between, the stale is not up to date, the new one is. everything works like expected. however, I have added 2 tags in the unstable_cache fetch, and when I invalidate them using an invalidateTags, the next request is (I guess) SSR'd, it takes around 300+ms, and is directly up to date. I thought I would get a stale and always hit the cache just like the standard ISR. is it the intended behavior ?
American Crocodile
I was searching for solutions for this problem, and yes it is the intended behaviour.
Answer
Paper waspOP
yes I figured that out aswell, I'll mark your answer
thanks for the reply