Quando usar: duas+ chamadas de dado independentes no mesmo componente.
Como: dispare os fetches sem await, guarde as Promises, depois await Promise.all([a, b]).
Trade-offs: uma falha rejeita tudo; use Promise.allSettled se falha parcial for tolerável.
Quando usar: layout/página lê cookies()/headers()/params mas parte da árvore pode ficar estática.
Como: não dê await no dado no componente top-level; passe a Promise a um filho envolto em <Suspense> que faz o await.
Trade-offs: mais um nível de componente e fallback visual; só o filho sai do shell estático.
Quando usar: Client Component precisa de dado do servidor sem bloquear render inicial.
Como: no Server Component, chame o fetch sem await, passe a Promise como prop dentro de <Suspense>; no filho, const data = use(promiseProp).
Trade-offs: a Promise não pode ser recriada a cada render do Client Component.
Quando usar: dado depende de cookie/sessão mas você quer manter prefetch (em vez de use cache: private).
Como: leia a runtime API fora do cache, extraia só o valor necessário e passe como argumento pra uma função use cache (entra na cache key).
Trade-offs: cache in-memory por instância a menos que use use cache: remote.
Quando usar: app precisa combinar dado público compartilhável com dado por-usuário.
Como: use cache pro shell público, use cache: remote pra compartilhar entre instâncias, use cache: private pro que depende de cookies/headers.
Trade-offs: mais complexidade de composição; exige cache handler remoto configurado pra segunda camada.
Quando usar: mutação precisa refletir imediatamente (read-your-own-writes) vs. pode tolerar stale-while-revalidate.
Como: updateTag() em Server Action expira na hora e força recompute; revalidateTag()/revalidatePath() serve stale enquanto revalida em background.
Trade-offs: updateTag só funciona em Server Actions; o próximo leitor paga o custo do recompute.
Quando usar: conteúdo de CMS/fonte externa muda raramente e imprevisivelmente.
Como: cachear com cacheTag + cacheLife('max'); configurar webhook da fonte pra chamar revalidateTag quando o conteúdo muda de fato.
Trade-offs: exige infra de webhook; TTL fixo é mais simples mas desperdiça revalidação.
Quando usar: rota precisa de valor único por request (ID, timestamp) sob Cache Components.
Como: chame connection() antes do valor não-determinístico, dentro de componente em <Suspense>.
Trade-offs: o componente sai do shell estático; alternativa é use cache se o valor puder ser compartilhado.
Quando usar: só um pedaço de UI (ex. search bar) precisa de estado/eventos.
Como: mantenha o pai como Server Component; "use client" só no filho interativo, importado normalmente.
Trade-offs: exige achar a fronteira certa; marcar o pai inteiro é mais simples mas infla o bundle.
Quando usar: autorização precisa ser consistente entre Server Components, Actions e Route Handlers.
Como: verifySession() memoizado com React.cache(), chamado por todo data fetcher; redireciona/lança erro se sessão inválida.
Trade-offs: exige disciplina pra nunca pular a DAL ao criar fetcher novo.
Quando usar: dado do banco tem campo sensível (senha, PII). Como: função retorna só os campos necessários, com lógica de visibilidade por role. Trade-offs: mais boilerplate por endpoint, evita vazamento acidental.
Quando usar: form via Server Action precisa de feedback de loading/erro sem JS extra.
Como: useActionState retorna [state, action, pending]; useOptimistic mostra valor otimista até a Action resolver.
Trade-offs: rollback em erro precisa ser tratado manualmente no reducer/state.
Quando usar: redirecionar por permissão/sessão em toda rota (incl. prefetched) sem custo de DB a cada request.
Como: decriptar cookie de sessão em proxy.ts, comparar contra protectedRoutes, NextResponse.redirect.
Trade-offs: nunca substitui checagem segura (DB) próxima da mutação; é só a primeira linha de defesa.
Quando usar: modal precisa ter URL própria (compartilhável) mas abrir sem navegação completa quando clicado in-app.
Como: slot @modal (Parallel) com pasta (.)photo (Intercepting) que sobrescreve a rota real só na navegação client-side.
Trade-offs: hard navigation/refresh renderiza a rota completa, não o modal.
Quando usar: app grande em Pages Router que não pode migrar tudo de uma vez.
Como: app/ e pages/ coexistem (App tem precedência); migre rota por rota, mantendo _app/_document até o fim.
Trade-offs: dois modelos de data fetching coexistindo até a migração terminar.
Quando usar: micro-frontend com múltiplos apps Next.js independentes sob um domínio.
Como: app principal usa rewrites() (ou basePath) pra rotear paths pra outros apps/deploys; assetPrefix evita colisão de assets.
Trade-offs: navegação entre zonas é hard navigation, não client-side.
Quando usar: deploy self-hosted (Docker) sem node_modules completo.
Como: output: 'standalone' gera .next/standalone com server.js mínimo e só os arquivos tracados via @vercel/nft.
Trade-offs: assets de public//.next/static precisam ser copiados manualmente pro standalone.
Quando usar: deploy multi-container/rolling onde cliente antigo pode bater em servidor novo.
Como: deploymentId (ou NEXT_DEPLOYMENT_ID) força hard navigation ao detectar deploy diferente entre cliente/servidor; generateBuildId mantém build ID consistente entre containers.
Trade-offs: hard navigation perde estado client-side na primeira troca pós-deploy.
Quando usar: self-hosted com múltiplas instâncias que precisam compartilhar cache de use cache/ISR.
Como: cacheHandler/cacheHandlers em next.config.js aponta pra storage compartilhado (Redis, etc.) em vez do cache em memória padrão.
Trade-offs: exige infra extra; sem isso, cada instância tem cache independente.
Quando usar: política de segurança estrita exige bloquear scripts/estilos inline não autorizados.
Como: gerar nonce aleatório em proxy.ts, propagar via header customizado, ler com headers() e aplicar em <script nonce>.
Trade-offs: nonce exige request dinâmica (não cacheável); SRI é alternativa que preserva static generation.
Quando usar: <Image> carrega de hosts externos (CMS, CDN de terceiros).
Como: images.remotePatterns no next.config.js, listando protocolo/hostname/pathname explicitamente.
Trade-offs: qualquer host novo exige redeploy do config; domains (legado) é menos preciso.
Quando usar: mudar searchParams (filtro, paginação) sem re-rodar data fetching da página.
Como: useSearchParams + router.push/replace (scroll: false), preservando o resto da query.
Trade-offs: Pages Router usa { shallow: true }; no App Router é implícito ao não mudar segmento.