Operação Cachorro Morno: O Erro de Iniciantes que um Insider Já Pagou Caro
Era uma sexta, 23h47. Olhei o dashboard do New Relic e vi um padrão estranho: picos de TTFB de 3s para usuários logados, zero para anônimos. O cache de página estava perfeito – mas apenas metade da história. O problema? Um plugin de membership que usava set_transient() para verificar status. O cache savava o HTML, mas o transient expirava no meio da requisição. Resultado: First Input Delay (FID) de 450ms para quem estava com a sessão quente. O Google Search Console acusava ‘dados insuficientes’ por meses. Até hoje, vejo tutoriais dizendo ‘use cache de página e pronto’. Não é tão simples.
Por que o Cache Tradicional Falha em Sites Dinâmicos
A grande ilusão do WordPress: acreditamos que um plugin de cache resolve tudo. Mas o Whole Page Cache (WPC) mata a personalização. Um site de e-commerce com 10 mil variações de produto? O cache gera 10 mil versões do HTML, estourando o disco. Um site com wp-login.php protegido por reCAPTCHA? O cache pode servir uma página de login antiga, expondo dados. O verdadeiro vilão? O transiente corrompido – dados temporários que plugins gravam no banco e esquecem de limpar.
- Problema: Transientes expiram, mas o cache não. O HTML servido referencia um transient que não existe mais.
- Sintoma: Páginas com conteúdo ‘pulado’, carrosséis vazios, menus sem itens.
- Métrica: Core Web Vitals – LCP sobe porque imagens carregam depois de um transient falso; CLS aumenta porque elementos somem/reaparecem.
A Solução Esquecida: Lukewarm Persistence
Conceito adaptado de stale-while-revalidate para edge. Em vez de servir página fria (sem transient) ou quente (com transient e risco de expiração), usamos lukewarm: o cache mantém o HTML mesmo se transient expirou, mas enfileira uma revalidação assíncrona no WordPress. Isso mantém o TTFB baixo (10ms) e evita picos de CPU. Implementei com nginx fastcgi_cache e um hook shutdown que verifica o _transient_timeout.
Implementação Passo a Passo (Sem Plugin)
- No
wp-config.php, definadefine('WP_CACHE_KEY_SALT', 'lukewarm'); - No nginx, crie
proxy_cache_key "$scheme$host$request_uri$cookie_logged_in";(para usuários logados, use cookie). - Acrescente um
mappara ignorar cookie de sessão efêmero. - No
functions.php, adicione:add_action('shutdown', function() { if (get_transient('user_data') === false) { wp_remote_get(home_url()); } });
Isso força uma revalidação em background, sem bloquear o usuário.
O Estudo de Caso: Site de Notícias com 500 mil visitas/dia
O site usava Redis Object Cache + Varnish. Os editores reportavam que, ao publicar uma matéria, ela não aparecia para 30% dos leitores por até 1 hora. O Varnish estava funcionando perfeitamente. O problema? O transiente de categoria – usado para listar posts recentes – expirava a cada 5 minutos, mas o Varnish ignorava a expiração. Solução: Reduzi o TTL do transient para 30 segundos e ajustei o Varnish para grace=1h com stale-while-revalidate. Resultado: LCP caiu de 4s para 1.2s, CLS de 0.25 para 0.02.
Dados Reais: Antes vs Depois
- Antes: TTFB médio 1.3s (anônimos), 4.5s (logados). Transientes corrompidos = 12% das páginas.
- Depois: TTFB 200ms (anônimos), 800ms (logados). Transientes servidos frios = 0%. Core Web Vitals todas verdes.
Checklist de Diagnóstico Rápido
- Verifique tabela
wp_optionscom query:SELECT * FROM wp_options WHERE option_name LIKE '%_transient_timeout%' AND option_value < UNIX_TIMESTAMP(); - Monitore logs do nginx para
MISSvsHIT. Se muitos MISS, ajuste TTL do cache. - Use
wp_cache_get()com$force=truepara bypass em ações críticas (login, checkout).
O Manifesto Técnico Contra o Cache Cego
WordPress não é um CMS estático. É um motor dinâmico que respira transientes. Negligenciar isso é construir uma casa de papel no meio de um furacão. A indústria fala de Headless WordPress, de Edge Functions, mas esquece que o banco de dados ainda é o gargalo. A solução não é mais plugins. É entender o fluxo de dados. O futuro do WP é um cache consciente: que saiba quando servir uma página fria, quando aquecer e, principalmente, quando deixar o transient morrer sem drama.