Cache e gclid: consulta do clique no anúncio, chave de cache da página e primeiro byte medido

O tratamento de cache do gclid consiste em ignorar a query gclid adicionada ao fim da URL de um clique em anúncio e responder com o arquivo de cache da URL sem query. Medições do primeiro byte por query e por estado do cache num servidor WordPress com Nginx + Apache mostraram que o gclid acrescentou 0,014–0,015 segundo, e atrasos de vários segundos só aconteceram quando o cache não pôde ser usado.
Medido dentro do mesmo servidor, o primeiro byte levou 0,014–0,015 segundo sem query e 0,029–0,030 segundo com as queries de clique em anúncio. Quando o WordPress montou a mesma página do zero sem cache, levou 3,639 e 3,260 segundos.
1️⃣ Cache e gclid: URLs de clique em anúncio e a chave de cache
Com a codificação automática do Google Ads ativada, [?gclid=valor] é adicionado ao fim da URL de quem clica no anúncio. Esse valor é um parâmetro que identifica o clique no anúncio, por isso muda de visitante para visitante, embora a mesma pessoa clicando de novo no mesmo anúncio possa receber o mesmo valor.
URLs reais de clique em anúncio raramente trazem só o gclid. Muitas vezes vêm junto gad_source, gad_campaignid e gbraid, e às vezes também wbraid.
https://example.com/sample-page/?gad_source=1&gad_campaignid=1234567890&gbraid=EXAMPLE&gclid=EXAMPLE
https://example.com/sample-page/?gclid=EXAMPLE&gbraid=EXAMPLE&wbraid=EXAMPLECom uma query no fim da URL, o navegador ainda abre a mesma página, mas para o cache é outro endereço. O padrão de cache HTTP (RFC 9111) define a chave de cache, o critério com que o cache escolhe uma resposta guardada, como formada no mínimo pelo método da requisição e pela URI de destino, e a URI de destino inclui a query string.
Se a query string entra na chave de cache como está, cada clique com um valor de gclid diferente vira um endereço novo. O CDN, o nginx e o WP Rocket, por onde a resposta passa, tratam essa query cada um por um critério diferente.
Se o CDN não tiver cópia ou se a chave de cache diferenciar as queries, a requisição segue para o servidor de origem. Dali em diante, a velocidade depende de o nginx e o WP Rocket encontrarem um arquivo de cache.
2️⃣ Entrega estática do nginx: requisições com query vão para o Apache
Mesmo com o arquivo de cache no disco, o nginx numa configuração Nginx + Apache não o entrega direto a uma requisição com query. Isso porque a configuração abaixo, que faz o nginx ler direto os arquivos de cache do WP Rocket, só monta o caminho do arquivo quando a query string está vazia.
# nginx.conf — bloco http: condições para pular o arquivo de cache
map $http_cookie $rocket_cookie {
default 0;
'~*wordpress_logged_in' 1;
'~*wp-postpass' 1;
'~*comment_author' 1;
'~*woocommerce_items' 1;
}
map $request_method $rocket_method {
default 1;
GET 0;
HEAD 0;
}
map $query_string $rocket_query {
default 1;
'' 0; # 0 só quando a query string está vazia
}
# bloco server
set $rocket_bypass '';
if ($rocket_cookie = 1) { set $rocket_bypass '1'; }
if ($rocket_method = 1) { set $rocket_bypass '1'; }
if ($rocket_query = 1) { set $rocket_bypass '1'; }
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index-https.html';
if ($rocket_bypass = '1') { set $rocket_file ''; }
location / {
try_files $rocket_file @apache; # para o Apache se o caminho estiver vazio ou o arquivo não existir
add_header X-Rocket-Nginx-Serving-File 'HIT' always; # marca as respostas que o nginx entregou direto do arquivo de cache
}[$rocket_query] só verifica se a query string inteira está vazia, então o gclid, que o WP Rocket ignora, é tratado como qualquer outra query. Se as cópias para celular ficam separadas, entra mais uma verificação que adiciona [-mobile] ao nome do arquivo.
As regras do [.htaccess] que o WP Rocket escreve para o Apache também exigem a query string vazia. Seja no nginx ou no Apache, a etapa que entrega o arquivo de cache direto, sem PHP, só vale para requisições sem query.
As requisições sem query traziam o cabeçalho [X-Rocket-Nginx-Serving-File: HIT], e as seis requisições com gclid e queries no estilo de anúncio não. O primeiro byte aumentou 0,014–0,015 segundo nas requisições com query porque entraram no caminho o Apache e o PHP lendo e devolvendo o arquivo de cache.
curl -so /dev/null -H 'Accept-Encoding: gzip' -w '%{time_starttransfer}\n' \
'https://example.com/sample-page/'0.015127curl -so /dev/null -H 'Accept-Encoding: gzip' -w '%{time_starttransfer}\n' \
'https://example.com/sample-page/?gclid=test123'0.029525curl -sI 'https://example.com/sample-page/' | grep -i x-rocket-nginx-serving-filex-rocket-nginx-serving-file: HIT[time_starttransfer] é o tempo desde a requisição até chegar o primeiro byte. Para medir dentro do servidor sem passar pelo CDN, adicione [--resolve example.com:443:127.0.0.1].
3️⃣ Lista de queries ignoradas do WP Rocket: o mesmo arquivo de cache
Não fazer cache de URLs com query é o padrão do WP Rocket, mas as queries de clique em anúncio são uma exceção. O WP Rocket tira os parâmetros da sua lista de ignoradas antes de decidir e, se não sobrar nenhuma query, responde com o arquivo de cache da URL sem query.
// wp-rocket/inc/classes/Buffer/class-tests.php (3.23.5.1)
public function get_query_params() {
// …
$params = array_diff_key( // tira primeiro as queries ignoradas
self::$get,
$this->config->get_config( 'cache_ignored_parameters' )
);
// …
}
public function can_process_query_string() {
// …
$params = $this->get_query_params();
if ( ! $params ) { // sem queries restantes: trata com cache
return self::memoize( __FUNCTION__, [], true );
}
// só passam lang · s · permalink_name · lp-variation-id e as queries colocadas em [Cache Query String(s)]
// …
}Se o que [get_query_params] devolve depois de tirar as queries ignoradas estiver vazio, o caminho do arquivo de cache também fica sendo o da URL sem query. A requisição com gclid passou pelo Apache e pelo PHP, mas o comentário de cache no fim do HTML era igual ao da requisição sem query, e o tamanho da resposta foi de 350.668 bytes, o mesmo do arquivo de cache (gzip).
A lista de queries ignoradas é uma lista padrão que o WP Rocket baixa dos próprios servidores uma vez por semana e salva em [wp-content/wp-rocket-config/dynamic-lists.json]. Em 17 de outubro de 2026, a lista inclui gclid, gbraid, wbraid, gad_source e gad_campaignid.
Se houver no meio uma única query fora da lista, o WP Rocket não usa o cache: a mesma página com uma query qualquer fora da lista foi montada do zero pelo WordPress, sem comentário de cache. Se as URLs dos seus anúncios levam queries de rastreamento criadas por você, esses cliques seguem esse caminho toda vez.
Para mudar a lista, use o plugin auxiliar indicado pelo WP Rocket. O plugin adiciona ou remove queries pelo filtro [rocket_cache_ignored_parameters] e gera de novo o arquivo de configuração do WP Rocket ao ser ativado ou desativado.
// trecho de WP Rocket | Ignore Query Strings 1.1.1 (plugin auxiliar da equipe de suporte do WP Rocket)
function define_ignored_parameters( array $params ) {
$params['new_query_string'] = 1; // adiciona às queries ignoradas
//unset ( $params['utm_source'] ); // tira das queries ignoradas
return $params;
}
add_filter( 'rocket_cache_ignored_parameters', __NAMESPACE__ . '\define_ignored_parameters', 999 );
register_activation_hook( __FILE__, __NAMESPACE__ . '\flush_wp_rocket' ); // executa rocket_generate_config_file() ao ativarO WP Rocket grava essa lista no arquivo de configuração com o nome do domínio dentro de [wp-content/wp-rocket-config/] e lê esse arquivo a cada requisição; por isso, se você só adicionar o filtro sem gerar de novo o arquivo de configuração, a nova lista não entra em vigor. As queries da lista compartilham o único arquivo de cache da URL base, seja qual for o valor, então não adicione queries cujo valor muda o que a página mostra.
Depois de adicionar ao plugin auxiliar [uk_test], que não estava na lista, e ativá-lo, o arquivo de configuração foi gerado de novo com essa query no fim da lista. Em seguida, a URL sem query e duas URLs com valores diferentes de [uk_test] foram requisitadas em sequência.
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/'
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?uk_test=abc'
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?uk_test=xyz'21390 0.025720
21390 0.025507
21390 0.027929As três requisições responderam com os mesmos 21.390 bytes em menos de 0,03 segundo, e o fim do HTML da requisição com [uk_test] foi aberto para conferir o horário do cache.
curl -s --compressed 'https://example.com/sample-page/?uk_test=abc' | tail -c 200ck=lazyLoadYoutubeIframe;}});</script></body>
</html>
<!-- This website is like a Rocket, isn't it? Performance optimized by WP Rocket. Learn more: https://wp-rocket.me - Debug: cached@1792248839 -->O horário do cache no comentário final era o mesmo do arquivo de cache da URL sem query. Antes de ativar o plugin auxiliar, a mesma requisição era montada do zero em 0,36–0,38 segundo, sem comentário de cache.
Mesmo depois de ativar, uma requisição que também trazia [foo], fora da lista, não usou o arquivo de cache e foi montada do zero.
Durante um minuto logo depois de gerar de novo o arquivo de configuração, as requisições com [uk_test] também foram montadas do zero. Com o PHP OPcache configurado para reverificar arquivos alterados a cada 60 segundos (revalidate_freq), as respostas só vieram do arquivo de cache depois de passado um minuto.
Mesmo depois de desativar e excluir o plugin auxiliar, a linha de [uk_test] ficou no arquivo de configuração. O código de desativação tenta remover o filtro, adicionado com prioridade 999, na prioridade padrão, então o arquivo de configuração é gerado de novo com o filtro ainda ativo. Só gerando o arquivo de configuração mais uma vez depois de excluir o plugin a query sai da lista.
4️⃣ Chave de cache do CDN: excluir queries de anúncio e requisições à origem
Se o CDN coloca a query string na chave de cache como está, cada clique com um valor de gclid diferente não encontra cópia, e a requisição vai até o servidor de origem. Tirar as queries por inteiro resolve isso, mas não serve para sites com URLs cujo conteúdo muda conforme a query, como resultados de busca; por isso é melhor tirar da chave de cache só as queries de anúncio.
Com as queries de anúncio retiradas assim, o CDN responde com a mesma cópia da URL sem query mesmo quando o valor do gclid muda, e só quando não tem cópia manda a requisição, com a query junto, ao servidor de origem.
# status de cache no CDN de duas requisições com valores de gclid diferentes (os nomes dos cabeçalhos variam conforme o CDN)
curl -sI 'https://example.com/sample-page/?gclid=test1' | grep -i -E 'cache|age'curl -sI 'https://example.com/sample-page/?gclid=test2' | grep -i -E 'cache|age'Se as duas requisições com valores diferentes forem HIT e as cópias tiverem sido guardadas no mesmo horário da URL sem query, esse CDN está deixando o gclid fora da chave de cache. A primeira visita num ponto sem cópia ainda passa pelo nginx e pelo WP Rocket do servidor de origem, mesmo que o CDN tire as queries de anúncio da chave.
5️⃣ O que atrasa os cliques em anúncios: um cache de página vazio
Quando a primeira página vinda de um anúncio carrega devagar, é fácil culpar o gclid por contornar o cache, mas, se existir um arquivo de cache, o mesmo arquivo é entregue mesmo com query. O que soma segundos ao primeiro byte é um arquivo de cache vazio, que obriga o WordPress a montar a página do zero.
Os arquivos de cache são apagados quando passa o prazo definido em Vida útil do cache; o padrão do WP Rocket é 10 horas. Salvar um post ou as configurações também apaga o cache relacionado, e quando a lista que o WP Rocket baixa uma vez por semana é trocada por uma versão nova e salva, o cache do site inteiro também é esvaziado.
Com o preload ligado, o WP Rocket reabre as URLs esvaziadas e preenche o cache de novo, e quem chega antes disso espera enquanto a página é montada. Uma requisição só com queries de anúncio também cria o arquivo de cache sob a URL sem query, então o clique em anúncio que encontra primeiro o cache vazio o preenche para o próximo visitante.
Logo depois de esvaziar o cache, a primeira requisição aberta com queries no estilo de anúncio não encontrou arquivo de cache e foi montada do zero em 0,341–0,369 segundo, e no mesmo segundo apareceu o arquivo de cache da URL sem query.
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/?gclid=EXAMPLE1'
ls -l --time-style='+%F %T' wp-content/cache/wp-rocket/example.com/sample-page/
curl -s -o /dev/null -w '%{size_download} %{time_starttransfer}\n' -H 'Accept-Encoding: gzip' 'https://example.com/sample-page/'21361 0.366881
Total 116
-rw-r--r-- 1 example nobody 90908 2026-10-17 23:56:38 index-https.html
-rw-r--r-- 1 example nobody 21385 2026-10-17 23:56:38 index-https.html_gzip
21385 0.025379As três vezes seguiram a mesma ordem, e a requisição sem query que veio em seguida foi respondida pelo novo arquivo de cache em 0,023–0,025 segundo. Como a requisição não veio de um celular, só os dois arquivos para desktop foram criados.
Para as URLs para onde seus anúncios apontam, confira você mesmo se existe arquivo de cache e quando foi criado; se as cópias para celular são feitas à parte, confira o arquivo de desktop e o de celular.
ls -l --time-style='+%F %T' wp-content/cache/wp-rocket/example.com/sample-page/Total 3520
-rw-r--r-- 1 example nobody 1445922 2026-10-17 14:07:44 index-https.html
-rw-r--r-- 1 example nobody 350668 2026-10-17 14:07:44 index-https.html_gzip
-rw-r--r-- 1 example nobody 1446862 2026-10-17 14:07:47 index-mobile-https.html
-rw-r--r-- 1 example nobody 351042 2026-10-17 14:07:47 index-mobile-https.html_gzipcurl -s --compressed 'https://example.com/sample-page/?gclid=test123' | tail -c 200n/1/wp-content/uploads/example-plugin/style.css' media='all' /></noscript></body>
</html>
<!-- Cached for great performance - Debug: cached@1792213663 -->Uma resposta vinda de um arquivo de cache traz, no comentário do fim do HTML, depois de [Debug: cached@], o horário em que o arquivo foi criado, em tempo Unix. Sem essa marca, foi o WordPress que montou a resposta do zero.
🔢 FAQ & conteúdo recomendado














ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.

