Capítulo 153 de 456

cacheLife

Core Idea

cacheLife define o tempo de vida de cache de uma função ou componente marcado com use cache, controlando por três eixos (stale/revalidate/expire) quando o cliente reusa dados, quando o servidor regenera em background e quando expira de vez.

Key Concepts

  • Pré-requisito: exige a flag cacheComponents: true em next.config.ts.
  • Escopo: só pode ser usado dentro de um escopo use cache (arquivo, função ou componente); chamar no nível de módulo lança erro.
  • stale: tempo (client-side) que o router usa cache sem checar o servidor; mínimo 30s é forçado no client cache.
  • revalidate: intervalo após o qual o servidor serve o cache e regenera em background (estilo ISR).
  • expire: tempo máximo sem tráfego após o qual o servidor regenera de forma síncrona na próxima requisição; deve ser maior que revalidate.
  • Perfis preset: default, seconds, minutes, hours, days, weeks, max.
  • Perfis customizados: definidos em next.config.ts sob cacheLife: { nome: {...} }; propriedades omitidas herdam do default.
  • Perfis inline: objeto passado direto para cacheLife({...}), aplicado só àquela função/componente.
  • Chamada condicional: cacheLife pode variar por branch de código, mas só uma chamada deve executar por invocação.

Code Examples

'use cache'
import { cacheLife } from 'next/cache'

export default async function BlogPage() {
  cacheLife('days') // Blog content updated daily
  const posts = await getBlogPosts()
  return <div>{/* render posts */}</div>
}
  • O que demonstra: uso de perfil preset dentro de um use cache scope.
// next.config.ts
const nextConfig = {
  cacheComponents: true,
  cacheLife: {
    biweekly: {
      stale: 60 * 60 * 24 * 14,
      revalidate: 60 * 60 * 24,
      expire: 60 * 60 * 24 * 14,
    },
  },
}
  • O que demonstra: definição de perfil customizado reutilizável, referenciado depois via cacheLife('biweekly').
async function getPostContent(slug: string) {
  'use cache'
  const post = await fetchPost(slug)
  cacheTag(`post-${slug}`)
  if (!post) {
    cacheLife('minutes')
    return null
  }
  cacheLife('days')
  return post.data
}
  • O que demonstra: cacheLife condicional, com durações diferentes conforme o resultado da busca.

Reference Tables

ProfileUse Casestalerevalidateexpire
defaultStandard content5 min15 minnever
secondsReal-time data30s1s1 min
minutesFrequently updated5 min1 min1h
hoursMultiple daily updates5 min1h1 dia
daysDaily updates5 min1 dia1 semana
weeksWeekly updates5 min1 semana30 dias
maxRarely changes5 min30 dias1 ano

Anti-patterns

  • Omitir cacheLife em use cache aninhado: se uma função com cache curto (ex. seconds) é usada dentro de outra use cache sem cacheLife explícito, o Next.js lança erro no prerender para evitar propagação silenciosa de comportamento dinâmico.
  • Abstrair cacheLife em utilitário compartilhado: dificulta ver o comportamento de cache no local da chamada; prefira chamar dentro da própria função/componente cacheado.
  • Redefinir perfis com nome temporal (days, hours) com valores que não batem com a expectativa intuitiva: confunde leitores; prefira criar perfil customizado com outro nome.

Key Takeaways

  1. Sempre declare cacheLife explicitamente em cada use cache para tornar o comportamento óbvio no call site.
  2. revalidate: 0 ou expire abaixo de 5 minutos exclui o conteúdo do prerender (vira "dynamic hole"); stale abaixo de 30s também exclui.
  3. Sem cacheLife explícito no escopo externo, um cache aninhado mais curto pode reduzir silenciosamente o default do escopo externo.
  4. stale controla o client cache via header x-nextjs-stale-time, não o Cache-Control HTTP.
  5. Ações de revalidação em Server Function (revalidateTag, revalidatePath, updateTag, refresh) limpam o client cache inteiro, ignorando stale.

Connects To

  • cacheComponents: flag de config necessária para habilitar cacheLife/cacheTag.
  • use cache: diretiva que define o escopo onde cacheLife pode ser chamada.
  • cacheTag / revalidateTag / updateTag: mecanismo complementar de invalidação por tag.