DesenvolvedorWordPress WhatsApp

Transients e cache de objeto no WordPress

Antes de pensar em CDN ou cache de página, há uma camada que o desenvolvedor controla direto no código: o cache de aplicação. Entenda quando usar transients e quando usar o cache de objeto, onde cada um é guardado e como evitar inchar a tabela wp_options.

Site lento por consultas repetidas? Posso ajudar.

Atualizado em 19/06/2026

Toda página do WordPress repete trabalho: consultas ao banco, chamadas a APIs externas, cálculos. O cache no nível da aplicação guarda o resultado desse trabalho para reaproveitá-lo, evitando refazer o que é caro. O WordPress oferece duas ferramentas para isso — a Transients API e o Object Cache (wp_cache_*) — e usá-las bem depende de entender uma diferença central: persistência. Este guia mostra os padrões de uso, onde cada cache mora e as armadilhas (a wp_options inchada, o autoload pesado) que transformam uma otimização em problema.

Transients: cache com expiração

Um transient é um valor nomeado com prazo de validade. A API tem três funções: set_transient( $chave, $valor, $expiracao ), get_transient( $chave ) e delete_transient( $chave ). O padrão de uso é sempre o mesmo — tenta o cache; se vazio, calcula, guarda e retorna:

<?php
/**
 * Retorna os posts mais comentados, cacheados por 12 horas.
 * Padrão: tenta o cache -> se false, computa -> guarda -> retorna.
 */
function meu_plugin_posts_populares() {
    $chave = 'meu_plugin_posts_populares';

    // 1) Tenta ler do cache.
    $posts = get_transient( $chave );

    // 2) get_transient retorna false se não existir OU se já expirou.
    if ( false === $posts ) {

        // 3) Trabalho caro: só roda quando o cache está vazio.
        $posts = get_posts( array(
            'orderby'      => 'comment_count',
            'order'        => 'DESC',
            'numberposts'  => 10,
        ) );

        // 4) Guarda com expiração (constantes de tempo do core).
        set_transient( $chave, $posts, 12 * HOUR_IN_SECONDS );
    }

    return $posts;
}

Pontos a observar:

Onde os transients ficam (e por que a wp_options incha)

Aqui está o detalhe que separa quem usa transients de quem usa bem. Sem um cache de objeto persistente instalado, cada transient vira duas linhas na tabela wp_options: uma com o valor (_transient_CHAVE) e outra com o timeout (_transient_timeout_CHAVE).

Em um site com muitas chaves dinâmicas (uma por produto, por usuário, por busca), isso gera milhares de linhas. Transients expirados nem sempre são removidos na hora — só quando relidos — então o lixo se acumula. A wp_options cresce, e como parte dela é carregada via autoload em toda requisição, o site desacelera. É uma causa frequente de WooCommerce lento.

Não marque valores grandes como autoload. Tudo com autoload = yes em wp_options é lido de uma só vez em cada requisição. Transients comuns não entram no autoload, mas options criadas com add_option( $chave, $valor, '', 'yes' ), sim — guarde no autoload só o que é pequeno e usado em quase toda página.

A boa notícia: instale um cache de objeto persistente (Redis ou Memcached, via drop-in) e o WordPress passa a gravar os transients nesse backend, em memória, sem tocar na wp_options. O mesmo código funciona, mas a leitura fica mais rápida e a tabela não incha. É a base do que tratamos em cache no WordPress.

Object Cache: evitando trabalho dentro da requisição

O cache de objeto (wp_cache_get, wp_cache_set, wp_cache_delete) guarda valores arbitrários, opcionalmente em grupos. Por padrão ele é não-persistente: existe apenas durante a requisição atual e é descartado ao final. Isso já é útil para não repetir a mesma consulta várias vezes na mesma página:

<?php
function meu_plugin_dados_autor( $autor_id ) {
    $grupo = 'meu_plugin';
    $chave = 'autor_' . absint( $autor_id );

    // $found indica se a chave existia (distingue de um valor null/false legítimo).
    $found = false;
    $dados = wp_cache_get( $chave, $grupo, false, $found );

    if ( false === $found ) {
        $dados = meu_plugin_consulta_cara( $autor_id ); // ex.: várias queries
        // Sem expiração explícita, dura até o fim da requisição
        // (ou até a expiração, se houver backend persistente).
        wp_cache_set( $chave, $dados, $grupo, HOUR_IN_SECONDS );
    }

    return $dados;
}

Repare no parâmetro $found passado por referência: ele resolve a ambiguidade do false que atrapalha os transients — você sabe se a chave existia, mesmo que o valor guardado seja false ou null.

Com um drop-in persistente (Redis/Memcached) instalado, o cache de objeto deixa de morrer no fim da requisição e passa a valer entre requisições e entre processos — e a expiração que você passa em wp_cache_set() finalmente é respeitada de verdade. É aí que wp_cache_* compete diretamente com transients, com a vantagem de não usar o banco.

Invalidando o cache na escrita

Cache que não é invalidado serve dado velho. Sempre que a fonte mudar, apague a chave para forçar o recálculo. O lugar natural é um hook de escrita, como save_post:

<?php
// Quando um post é salvo, invalida o cache dos "posts populares".
add_action( 'save_post', 'meu_plugin_limpar_cache' );

function meu_plugin_limpar_cache( $post_id ) {
    if ( wp_is_post_revision( $post_id ) ) {
        return; // ignora revisões
    }

    // Apaga o transient (volta a computar na próxima leitura).
    delete_transient( 'meu_plugin_posts_populares' );

    // Se também usou cache de objeto, invalide a chave correspondente.
    wp_cache_delete( 'autor_' . get_post_field( 'post_author', $post_id ), 'meu_plugin' );
}

Combine as duas estratégias: expiração como rede de segurança (o dado não fica eterno, mesmo se você esquecer de invalidar em algum caminho) e invalidação explícita na escrita (o usuário não vê dado desatualizado).

Multisite: site transients

Em uma rede multisite, os transients comuns são por blog. Para um valor compartilhado por toda a rede, use os site transients: set_site_transient(), get_site_transient() e delete_site_transient(). Sem cache de objeto persistente, eles ficam na wp_sitemeta (rede), não na wp_options de um blog. A semântica é idêntica — só muda o escopo.

Transient × Object Cache: quando usar cada um

Transient APIObject Cache (wp_cache_*)
Persistência padrãoPersistente (vai para wp_options)Não-persistente (só na requisição)
Com Redis/MemcachedVai para o backend, fora do bancoTorna-se persistente entre requisições
ExpiraçãoSempre suportadaSuportada de fato só com backend persistente
EscopoPor site (ou rede, com site_transient)Por requisição (ou global, com backend)
Armazena false com segurança?Não (ambíguo)Sim (via parâmetro $found)
Quando usarResultado que precisa sobreviver entre requisições (API externa, lista pesada)Evitar repetir o mesmo trabalho dentro de uma requisição

Resumo da decisão: se você instalou um cache de objeto persistente, os dois convergem e a Transients API é a forma mais portável de escrever (funciona com ou sem Redis). Se não instalou, prefira transients para o que precisa durar entre requisições — e use cache de objeto para deduplicar consultas dentro de uma página, ciente de que ele some no fim. Combinado a uma WP_Query bem escrita, é o jeito mais barato de cortar carga do banco.

Quer cache de objeto persistente e transients sob controle?

Configuro Redis/Memcached, reviso o uso de transients e limpo a wp_options inchada para o seu site (ou loja WooCommerce) voar. Me chame no WhatsApp.

WhatsApp: (43) 99932-9697

ou e-mail: [email protected]

Perguntas frequentes

Qual a diferença entre transient e cache de objeto?

O transient tem expiração própria e é potencialmente persistente: sem um cache de objeto persistente instalado, ele é gravado na tabela wp_options e sobrevive entre requisições. O cache de objeto (wp_cache_*) é, por padrão, não-persistente: vive apenas durante uma única requisição e some ao final dela — a não ser que você instale um drop-in (Redis, Memcached). Regra prática: use transient para o que precisa sobreviver entre requisições; use cache de objeto para evitar repetir o mesmo trabalho dentro de uma requisição.

Onde os transients ficam guardados?

Depende do ambiente. Sem cache de objeto persistente, ficam na tabela wp_options (em dois registros por transient: o valor e o timeout). Com um cache de objeto persistente instalado (Redis/Memcached via drop-in object-cache.php), o WordPress redireciona os transients para esse backend e não toca na wp_options. Por isso, em sites sem Redis, transients mal gerenciados podem inchar a wp_options e afetar a performance.

Transient expirado é apagado automaticamente?

Não na hora exata. Quando você chama get_transient() e o valor já expirou, o WordPress retorna false e remove aquele registro. Mas transients expirados que nunca mais são lidos podem permanecer na wp_options por bastante tempo (são limpos por rotinas eventuais). Em lojas movimentadas isso vira lixo acumulado — tema ligado a WooCommerce lento.

O que é o autoload em options e por que importa para cache?

Cada linha de wp_options tem uma coluna autoload. Tudo marcado como autoload = yes é carregado de uma vez, em toda requisição. Transients normais não entram no autoload, mas valores guardados via add_option()/update_option() com autoload ligado, sim — se forem grandes ou numerosos, pesam em cada carregamento. Guarde no autoload apenas o que é pequeno e usado em quase toda página.

Como funcionam os transients em multisite?

Os transients comuns são por site (blog) da rede. Para um valor compartilhado por toda a rede, use os site transients: set_site_transient(), get_site_transient() e delete_site_transient(). Sem cache de objeto persistente, eles vão para a tabela wp_sitemeta em vez da wp_options de um blog específico.

Preciso invalidar o cache manualmente?

Sim, sempre que o dado de origem mudar. Transients expiram por tempo, mas se a informação mudou antes da expiração você serve dado velho. O padrão é apagar a chave (delete_transient() / wp_cache_delete()) em um hook de escrita — por exemplo, save_post ao publicar um post — para que o próximo acesso recompute. Definir expiração curta ajuda como rede de segurança, mas não substitui a invalidação explícita.

Referências oficiais

  1. WordPress.org — Transients API (Common APIs)
  2. WordPress.org — set_transient() (Code Reference)
  3. WordPress.org — wp_cache_get() (Code Reference)
  4. WordPress.org — Code Reference
Tem alguma dúvida? Ficarei feliz em ajudar. Clique Aqui