Arquivo de Caso · INV-0053
Dez minutos de erros 500 durante um pico no LinkedIn — sem nenhum cache de fallback
Uma publicação no LinkedIn gerou um grande volume de novos visitantes para o site da SimUser AI. O CMS não suportou a carga e começou a retornar erros 503. Sem camada de cache e sem fallback, cada requisição virou um erro 500 — por dez minutos seguidos.
A Arquitetura que Falhou
Cada requisição de página buscava o conteúdo diretamente no CMS em tempo real. Não havia cache entre a função Lambda e o CMS — tornando o CMS um ponto único de falha.
sem fallback — toda requisição → 500
Tráfego vs. Erros 5xx
O volume de requisições e a taxa de erros subiram juntos. O CMS não aguentou o pico — cada novo visitante recebia um erro 500 em vez da página.
{"level":"error","msg":"CMS API request failed","endpoint":"https://cms.simuser.ai/api/pages/get-started","status":503,"elapsedMs":4200}{"level":"warn","msg":"CMS unavailable — no fallback cache found for path","path":"/get-started"}{"level":"error","msg":"Rendering error page","statusCode":500,"reason":"CMS_UNAVAILABLE","path":"/get-started"}
O Cache que Nunca Foi Aquecido
Um scan no DynamoDB confirmou a causa raiz: 80 registros de cache, todos com revalidatedAt: 1 — o sentinel de época Unix para "nunca revalidado desde o deploy".
DynamoDB · WebsiteRevalidationTable
80 registrosDescoberta Crítica
Todos os 80 registros de cache para a página afetada mostram revalidatedAt: 1 — o cache foi definido no deploy e nunca foi aquecido. Quando o CMS ficou indisponível, não havia nada para servir.
Antes e Depois: Estratégia de Cache
A correção foi estrutural — migrar de SSR a cada requisição para ISR com janela de revalidação de 5 minutos e fallback try/catch para o cache obsoleto.
Antes
SSR — busca a cada requisição, sem cache
Depois
ISR + fallback — cache obsoleto é melhor que erro 500
Impacto nos Negócios
Leads estimados perdidos
~40
Com base na taxa de conversão média e no volume de tráfego durante a janela de 10 minutos. Cada visitante que encontrou um erro 500 na página Get Started era um potencial cadastro de trial.
Estimativa: 400 visitantes × 10% de taxa de cadastro × 10 min de interrupção
Causa Raiz e Correção
A página usava SSR puro com uma busca síncrona ao CMS em cada requisição. A correção: migrar para ISR com revalidate: 300 e um fallback try/catch que serve conteúdo obsoleto em vez de lançar erro.
// pages/get-started — SSR: fetch on every request
export default async function GetStartedPage() {
const content = await fetch('https://cms.simuser.ai/api/pages/get-started')
.then(r => r.json());
// CMS 503 → this throws → Next renders 500 to the user
return <PageContent data={content} />;
}// ISR — cached for 5 min, tolerant to CMS outages
export const revalidate = 300; // 5 minutes
export default async function GetStartedPage() {
const content = await fetchWithFallback();
return <PageContent data={content} />;
}
async function fetchWithFallback() {
try {
const res = await fetch('https://cms.simuser.ai/api/pages/get-started', {
next: { revalidate: 300 },
signal: AbortSignal.timeout(3000),
});
if (!res.ok) throw new Error(`CMS returned ${res.status}`);
return await res.json();
} catch (err) {
console.error({ msg: 'CMS fetch failed — serving stale cache', err });
return null; // Next.js serves ISR cache automatically
}
}Pare de caçar a causa raiz sob pressão
— deixe o CauseFlow encontrar.
O CauseFlow correlaciona registros do DynamoDB, logs do Lambda e métricas do CloudWatch automaticamente — sem triagem manual de logs, sem arqueologia de post-mortem.