Query string que não fura o cache do Cloudflare
O ?v= só fura o cache do Cloudflare quando a chave de cache da zona inclui a query string. No nível padrão ela inclui, mas uma regra de cache para HTML pode ignorar a query, e aí o ?v= devolve a mesma cópia da borda. Em 25 de setembro de 2026, medi cinco URLs de um site com duas query strings diferentes em cada uma, e todas voltaram HIT com a mesma idade da versão sem query. O teste confiável compara cf-cache-status e age entre duas queries diferentes, e não confia no cabeçalho do plugin de cache da origem.
Principais pontos
- A documentação da Cloudflare diz que o nível Standard, o padrão, entrega um recurso diferente cada vez que a query string muda.
- Pela mesma documentação, o nível Ignore Query String só desconsidera a query em extensões de arquivo estático.
- Em 25 de setembro de 2026, a Home de lucasferrazseo.com respondeu HIT com age 3460 sem query e com duas query strings diferentes.
- Na mesma leitura, o cabeçalho x-litespeed-cache dizia miss em uma resposta servida pelo Cloudflare com age de 3479 segundos.
- Duas query strings diferentes com o mesmo age provam que a chave de cache ignora a query naquela URL.
O que a query string faz na chave de cache?
O ?v= só gera uma cópia nova no Cloudflare quando a chave de cache da zona inclui a query string. A documentação da Cloudflare descreve três níveis. No Standard, o padrão, cada query diferente entrega um recurso diferente. No Ignore Query String, o mesmo recurso vai para todo mundo, qualquer que seja a query. E no No Query String, só a URL sem query sai do cache.
Dois detalhes da mesma documentação mudam a leitura. O nível Ignore Query String só vale para extensões de arquivo estático, como CSS e JS. E o Cloudflare não guarda HTML por padrão: sem uma regra de cache para páginas, o HTML volta como DYNAMIC e vem sempre da origem. Quando um site guarda HTML na borda, quem decide se a query entra na chave é a regra de cache que alguém criou, não o nível padrão.
O que medi em cinco URLs?
Em 25 de setembro de 2026, as cinco URLs que testei devolveram a mesma cópia da borda com e sem query string. Pedi cada página três vezes, na sequência: sem query, com ?v= e um valor, e com ?v= e outro valor. As requisições saíram sem cookie e com o cache do navegador desligado.
| URL | Sem query | ?v=A | ?v=B |
|---|---|---|---|
| / | HIT, age 3460 | HIT, age 3460 | HIT, age 3460 |
| /glossario/ | HIT, age 2998 | HIT, age 2998 | HIT, age 2998 |
| /glossario-de-geo/ | MISS | HIT, age 0 | HIT, age 0 |
| /servicos/consultoria-de-seo/ | MISS | HIT, age 0 | HIT, age 0 |
| /blog/presenca-digital/kpis-de-geo/ | MISS | HIT, age 0 | HIT, age 0 |
Nas duas primeiras, as três respostas têm a mesma idade, então são a mesma cópia. Nas outras três, o pedido sem query gerou a cópia, e os pedidos com query caíram nela um segundo depois.
O resultado contrariou a regra que eu mesmo seguia. Nas instruções do projeto, o ?v= com timestamp era o jeito de ver a versão atual das páginas. Isso vale para o cache da origem, mas não para a borda do Cloudflare nessa zona. Em 24 de setembro, a página /glossario/ ainda incluía a query na chave, e no dia 25 já não incluía, o que mostra que o comportamento pode mudar sem aviso.
Em 24 de setembro, a página /glossario/ ainda incluía a query na chave, e no dia 25 já não incluía, o que mostra que o comportamento pode mudar sem aviso.
Lucas Ferraz, especialista em SEO
O cabeçalho do LiteSpeed que viaja congelado
Quando há dois caches em série, o cabeçalho do cache da origem descreve o momento em que a borda buscou a página, e não o momento da sua requisição. Na mesma leitura, a Home voltou com cf-cache-status HIT, age de 3479 segundos e x-litespeed-cache igual a miss. Lido sozinho, o miss sugere que a página acabou de ser gerada. Não acabou. O comentário do plugin no fim do HTML dizia que a página foi gravada às 22h19 daquela noite, e o last-modified batia com esse horário, quase uma hora antes.
O Cloudflare guarda a resposta inteira, cabeçalhos incluídos. O miss foi verdade uma vez, quando a borda pediu a página à origem, e desde então viaja congelado dentro da cópia. Por isso não uso cabeçalho do plugin de origem para dizer se a página é nova quando há CDN na frente.
Como verificar de verdade?
A verificação confiável compara as respostas da borda entre si, e não confia em um cabeçalho isolado. Faço quatro leituras, nesta ordem:
- cf-cache-status da URL sem query. HIT é borda, MISS é origem com cópia recém-criada, DYNAMIC é origem sem cache.
- A mesma URL com duas queries diferentes. Se o age vier igual nas três, a query não entra na chave, e o ?v= não serve para furar o cache.
- O age ao lado do date. Idade alta significa que a cópia foi feita há tempo, e é a medida de quão velha é a página que você está lendo.
- O last-modified ou o comentário do plugin de cache no fim do HTML. Eles dizem quando a origem gerou aquela versão, não quando você a recebeu.
Para ver a versão nova de verdade, o caminho é o purge da URL nas duas camadas, com a leitura seguinte mostrando MISS e age zerado. No site pessoal, uso uma regra de bypass para um caminho que só serve markdown, e ela vem antes da regra de cache.
O que a leitura errada custou?
O erro não ficou só na verificação: a mesma chave de cache causou um problema de medição que só apareceu quando abri o Clarity. Como as leituras com ?v= voltavam da borda, eu achava que estava vendo a página gerada na hora. Não estava, e a chave de cache que ignora a query também ignora cookie. Contei o efeito disso no GA4 e no consentimento de cookies no texto sobre consentimento, cache e tráfego de IA. A regra que ficou é curta: antes de qualquer diagnóstico ao vivo, uma leitura de cf-cache-status e age em duas queries diferentes.
Nota de método
- O que foi medido
- cf-cache-status, age, x-litespeed-cache, cache-control e last-modified de cinco URLs de lucasferrazseo.com, cada uma sem query e com duas query strings diferentes.
- Quando
- 25 de setembro de 2026, por volta das 23h15 no horário de Brasília.
- Como
- Requisições fetch no navegador, sem cookie e com cache do navegador desligado, na sequência sem query, ?v=A e ?v=B.
- Limitação
- Uma zona do Cloudflare e uma noite. A configuração exata da regra de cache não foi lida no painel; o comportamento foi inferido das respostas.
Os termos de medição estão definidos no vocabulário de medição, e o protocolo das rodadas na política editorial.
O que a IA desdobra desta pergunta?
Quando alguém faz esta busca em uma IA, o sistema abre subperguntas antes de responder. Estas são as que apareceram na medição, e onde cada uma é respondida.
Perguntas frequentes
Se o Cloudflare não guarda HTML por padrão, por que o ?v= falharia?
Porque muitos sites criam uma regra de cache para HTML, seja para velocidade, seja para aliviar a hospedagem. Sem regra, o HTML volta como DYNAMIC e sempre vem da origem, e o ?v= nem faz diferença. Com regra, o comportamento depende da chave de cache que a regra define, e é aí que a query pode ser ignorada.
Como forçar a versão nova para conferir uma mudança?
O caminho seguro é o purge da URL no Cloudflare, e depois do cache da origem, conferindo em seguida um MISS e um age zerado. Outra saída é uma regra de bypass para uma condição que só você usa, como um cabeçalho ou um caminho de teste. Trocar o valor do ?v= só funciona quando a medição mostra que a query entra na chave.
O age sempre aparece quando a página vem do cache?
Não sempre. Ele aparece nas respostas HIT, mas não nas MISS, DYNAMIC e BYPASS, e com cache em camadas o primeiro HIT de uma borda pode vir sem ele. Por isso a leitura combina cf-cache-status, age e a comparação entre duas queries, e não depende de um cabeçalho só.
Fontes citadas
Versão em markdown para agentes de IA: https://lucasferraz.com/blog/cache-do-cloudflare-e-query-string/md/