Capítulo 43 de 456

How Revalidation Works

Core Idea

Explica o funcionamento interno da revalidação de cache no Next.js (tags, consistência HTML/RSC, coordenação multi-instância) para quem implementa cache handlers customizados ou debuga comportamento de revalidação em produção.

Key Concepts

  • Time-based revalidation: stale-while-revalidate; conteúdo em cache é servido enquanto uma regeneração em background é disparada ao exceder cacheLife/revalidate.
  • On-demand revalidation: invalida explicitamente via revalidateTag() ou revalidatePath(); a próxima requisição dispara render fresco.
  • Explicit tags: definidas pelo dev com cacheTag() dentro de use cache, ou via next: { tags: [...] } num fetch.
  • Soft tags: geradas automaticamente por Next.js com prefixo _N_T_, uma por segmento de rota (layout) mais a rota folha; permitem que revalidatePath() funcione pelo mesmo sistema de tags.
  • updateTags(): hook do cache handler chamado quando revalidateTag() roda; deve escrever o evento de invalidação em storage compartilhado (Redis, DB).
  • refreshTags(): hook chamado periodicamente antes de cada nova requisição; deve ler o storage compartilhado e atualizar o estado local de tags. Deve capturar erros internamente, senão a exceção propaga como falha de requisição.
  • getExpiration(): retorna o timestamp de revalidação mais recente entre as tags fornecidas, ou 0 se nenhuma foi revalidada; pode retornar Infinity para sinalizar que as soft tags devem ser passadas a get().
  • deploymentId: mitiga cross-deployment skew forçando hard navigation quando o cliente detecta deployment ID diferente do servidor.

Reference Tables

Cenário de falhaComportamento
Falha de escrita no cacheResposta ainda é servida (escrita é assíncrona); entrada é perdida, próxima requisição gera render fresco
Falha de leitura no cacheHandler deve capturar erro e retornar undefined (sinal de miss); erro lançado propaga como erro de render, não como miss
Inconsistência HTML/RSCCachear juntos com mesmo TTL e respeitar header Vary evita mismatch em navegação client-side
Cross-deployment skewConfigurar deploymentId para forçar hard navigation

Anti-patterns

  • Cachear HTML e RSC payload separadamente com TTLs diferentes: gera mismatch de conteúdo durante navegação client-side; sempre cachear juntos e respeitar o header Vary.
  • refreshTags() sem try/catch: uma exceção não capturada propaga como falha de requisição em vez de degradar graciosamente.
  • Rodar múltiplas instâncias sem coordenação de tags: revalidateTag() só invalida a instância que recebeu a chamada; outras seguem servindo conteúdo stale até implementar updateTags()/refreshTags().

Key Takeaways

  1. Revalidação regenera HTML e RSC payload juntos, do mesmo component tree, para manter navegação client-side consistente.
  2. Soft tags (_N_T_...) fazem revalidatePath() funcionar através do mesmo sistema de tags usado por revalidateTag().
  3. Em multi-instância, sem cache handler customizado a invalidação on-demand só afeta a instância que recebeu a chamada.
  4. O sistema prioriza disponibilidade sobre consistência estrita: falhas de cache degradam performance, não quebram a aplicação.
  5. Handlers de cache devem sempre retornar undefined em erro de leitura, nunca lançar exceção, para sinalizar miss corretamente.

Connects To

  • ISR (ch044): usa o mesmo sistema de tags para revalidação time-based e on-demand.
  • cacheHandlers: onde updateTags(), refreshTags() e getExpiration() são implementados na prática.
  • CDN Caching: trata do header Vary e políticas de TTL para HTML/RSC em edge caches.