Caché y gclid: la consulta del clic en un anuncio, la clave de caché de la página y el primer byte medido

El tratamiento de gclid en la caché consiste en ignorar el parámetro gclid que se añade al final de la URL de un clic en un anuncio y responder con el archivo de caché de la dirección sin parámetros. Al medir el tiempo hasta el primer byte según los parámetros y la caché en un servidor WordPress con Nginx + Apache, gclid añadió 0,014–0,015 segundos, y los retrasos de varios segundos solo aparecieron cuando no se pudo usar la caché.
Medido dentro del mismo servidor, el tiempo hasta el primer byte fue de 0,014–0,015 segundos sin parámetros y de 0,029–0,030 segundos con los parámetros de clic en anuncios. Cuando WordPress generó la misma página desde cero sin caché, tardó 3,639 y 3,260 segundos.
1️⃣ Caché y gclid: URL de clic en anuncios y clave de caché
Con el etiquetado automático de Google Ads, se añade [?gclid=valor] al final de la URL de los visitantes que hacen clic en un anuncio. Este valor es un parámetro que identifica el clic, así que cambia de un visitante a otro, aunque si la misma persona vuelve a pulsar el mismo anuncio puede repetirse el valor.
Las URL reales de clic en anuncios no llevan solo gclid. A menudo se añaden también gad_source, gad_campaignid y gbraid, y a veces 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=EXAMPLEAunque la URL lleve parámetros al final, el navegador abre la misma página, pero para la caché es otra dirección. El estándar de caché HTTP (RFC 9111) define la clave de caché, el criterio con el que una caché elige una respuesta guardada, como formada al menos por el método de la petición y la URI de destino, y la URI de destino incluye la cadena de consulta.
Si la cadena de consulta entra tal cual en la clave de caché, cada clic con un valor de gclid distinto se convierte en una dirección nueva. La CDN, nginx y WP Rocket, por los que pasa la respuesta, tratan estos parámetros con criterios distintos.
Si la CDN no tiene copia o su clave de caché distingue los parámetros, la petición llega al servidor de origen. A partir de ahí, la velocidad depende de que nginx y WP Rocket encuentren un archivo de caché.
2️⃣ Entrega estática de nginx: con parámetros, la petición pasa a Apache
Aunque el archivo de caché esté en disco, nginx en una configuración Nginx + Apache no lo entrega directamente a una petición con parámetros. Se debe a que la configuración de abajo, que permite a nginx leer directamente los archivos de caché de WP Rocket, solo construye la ruta del archivo cuando la cadena de consulta está vacía.
# nginx.conf — bloque http: condiciones para saltarse el archivo de caché
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 solo si la cadena de consulta está vacía
}
# bloque 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; # a Apache si la ruta está vacía o falta el archivo
add_header X-Rocket-Nginx-Serving-File 'HIT' always; # indica que nginx respondió directamente con el archivo de caché
}[$rocket_query] solo comprueba si toda la cadena de consulta está vacía, así que gclid, que WP Rocket ignora, se trata igual que cualquier otro parámetro. Si se guardan copias móviles aparte, se añade una comprobación más que pone [-mobile] en el nombre del archivo.
Las reglas [.htaccess] que WP Rocket crea para Apache también exigen que la cadena de consulta esté vacía. Tanto en nginx como en Apache, el paso que entrega el archivo de caché directamente sin PHP solo se aplica a peticiones sin parámetros.
Las peticiones sin parámetros llevaban la cabecera [X-Rocket-Nginx-Serving-File: HIT], y las seis peticiones con gclid y parámetros con forma de anuncio no la tenían. El tiempo hasta el primer byte creció 0,014–0,015 segundos en las peticiones con parámetros porque se sumó el paso de Apache y PHP leyendo el archivo de caché para responder.
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] es el tiempo desde la petición hasta recibir el primer byte. Para medir dentro del servidor sin pasar por la CDN, añade [--resolve example.com:443:127.0.0.1].
3️⃣ Lista de parámetros ignorados de WP Rocket: misma respuesta desde caché
No guardar en caché las URL con parámetros es el comportamiento predeterminado de WP Rocket, pero los parámetros de clic en anuncios son una excepción. WP Rocket quita antes de decidir los parámetros que están en su lista de ignorados y, si no queda ninguno, responde con el archivo de caché de la dirección sin parámetros.
// wp-rocket/inc/classes/Buffer/class-tests.php (3.23.5.1)
public function get_query_params() {
// …
$params = array_diff_key( // quita primero los parámetros ignorados
self::$get,
$this->config->get_config( 'cache_ignored_parameters' )
);
// …
}
public function can_process_query_string() {
// …
$params = $this->get_query_params();
if ( ! $params ) { // sin parámetros restantes: se sirve desde la caché
return self::memoize( __FUNCTION__, [], true );
}
// solo pasan lang · s · permalink_name · lp-variation-id y los parámetros añadidos a [Cache Query String(s)]
// …
}Si lo que devuelve [get_query_params] tras quitar los parámetros ignorados está vacío, la ruta del archivo de caché también se fija en la dirección sin parámetros. La petición con gclid pasó por Apache y PHP, pero el comentario de caché al final del HTML era el mismo que en la petición sin parámetros, y el tamaño de la respuesta fue de 350.668 bytes, igual que el archivo de caché (gzip).
La lista de parámetros ignorados es una lista predeterminada que WP Rocket descarga una vez por semana de sus propios servidores y guarda en [wp-content/wp-rocket-config/dynamic-lists.json]. A 17 de octubre de 2026, la lista incluye gclid, gbraid, wbraid, gad_source y gad_campaignid.
Si se mezcla aunque sea un parámetro que no está en la lista, WP Rocket no usa la caché: la misma página con un parámetro cualquiera fuera de la lista la generó WordPress desde cero, sin comentario de caché. Si tus URL de anuncios llevan parámetros de seguimiento propios, esos clics siguen esta ruta cada vez.
Para cambiar la lista, usa el plugin auxiliar que indica WP Rocket. El plugin añade o quita parámetros con el filtro [rocket_cache_ignored_parameters] y regenera el archivo de configuración de WP Rocket al activarlo y desactivarlo.
// extracto de WP Rocket | Ignore Query Strings 1.1.1 (plugin auxiliar del equipo de soporte de WP Rocket)
function define_ignored_parameters( array $params ) {
$params['new_query_string'] = 1; // añadir a los parámetros ignorados
//unset ( $params['utm_source'] ); // quitar de los parámetros ignorados
return $params;
}
add_filter( 'rocket_cache_ignored_parameters', __NAMESPACE__ . '\define_ignored_parameters', 999 );
register_activation_hook( __FILE__, __NAMESPACE__ . '\flush_wp_rocket' ); // al activar, ejecuta rocket_generate_config_file()WP Rocket escribe esta lista en el archivo de configuración con el nombre del dominio dentro de [wp-content/wp-rocket-config/] y lo lee en cada petición, así que si solo añades el filtro sin regenerar ese archivo, la nueva lista no se aplica. Los parámetros de la lista usan un único archivo de caché, el de la dirección base, sea cual sea su valor, así que no añadas parámetros cuyo valor cambie el contenido de la página.
Tras añadir al plugin auxiliar [uk_test], que no estaba en la lista, y activarlo, se regeneró el archivo de configuración con ese parámetro al final de la lista. Después se pidieron por orden la dirección sin parámetros y dos direcciones con valores distintos de [uk_test].
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.027929Las tres peticiones devolvieron los mismos 21.390 bytes en menos de 0,03 segundos, y se abrió el final del HTML de la petición con [uk_test] para comprobar la hora de la caché.
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 -->La hora de caché del comentario final coincidía con la del archivo de caché de la dirección sin parámetros. Antes de activar el plugin auxiliar, la misma petición se generaba desde cero en 0,36–0,38 segundos, sin comentario de caché.
Incluso después de activarlo, una petición que llevaba además [foo], que no está en la lista, no usó el archivo de caché y se generó desde cero.
Durante el minuto siguiente a regenerar el archivo de configuración, las peticiones con [uk_test] también se generaron desde cero. Como PHP OPcache vuelve a comprobar los archivos cambiados cada 60 segundos (revalidate_freq) en esta configuración, la respuesta salió del archivo de caché pasado un minuto.
Aunque se desactivó y borró el plugin auxiliar, la línea [uk_test] siguió en el archivo de configuración. El código que se ejecuta al desactivarlo intenta quitar con la prioridad predeterminada el filtro añadido con prioridad 999, así que el archivo se regenera con el filtro todavía puesto. Solo al regenerar el archivo una vez más tras borrar el plugin desaparece de la lista.
4️⃣ Clave de caché de la CDN: excluir los parámetros de anuncios y peticiones al origen
Si la CDN mete la cadena de consulta tal cual en la clave de caché, cada clic con un valor de gclid distinto se queda sin copia y la petición llega hasta el servidor de origen. Quitar todos los parámetros lo resuelve, pero no conviene en sitios con direcciones cuyo contenido cambia según los parámetros, como los resultados de búsqueda, así que es mejor quitar de la clave de caché solo los parámetros de anuncios.
Así, sin los parámetros de anuncio, la CDN responde con la misma copia que la dirección sin parámetros aunque cambie el valor de gclid, y solo cuando no tiene copia pide al servidor de origen con los parámetros.
# estado de caché de la CDN para dos peticiones con distinto gclid (el nombre de la cabecera depende de la 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'Si las dos peticiones con valores distintos son HIT y la copia se guardó a la misma hora que la de la dirección sin parámetros, esa CDN está dejando gclid fuera de la clave de caché. La primera visita a un nodo sin copia sigue pasando por nginx y WP Rocket en el servidor de origen, aunque la CDN quite los parámetros de anuncio de la clave.
5️⃣ La causa de la lentitud tras un clic en un anuncio: una caché de página vacía
Si la primera página que llega desde un anuncio tarda, es fácil culpar a gclid de saltarse la caché, pero si existe el archivo de caché, se responde con él aunque haya parámetros. Lo que suma segundos al tiempo hasta el primer byte es un archivo de caché vacío, que obliga a WordPress a generar la página desde cero.
Los archivos de caché se borran cuando pasa la Vida útil de la caché (10 horas por defecto en WP Rocket). Al guardar una entrada o los ajustes también se borra la caché relacionada, y cuando la lista que WP Rocket descarga una vez por semana se sustituye por una versión nueva, se vacía toda la caché del sitio.
Con la precarga activada, WP Rocket vuelve a abrir las direcciones vaciadas y rellena la caché; los visitantes que llegan antes esperan mientras se genera la página. Una petición con solo parámetros de anuncio también crea el archivo de caché con la dirección sin parámetros, así que el clic en un anuncio que encuentra primero la caché vacía la rellena para el siguiente visitante.
Justo después de vaciar la caché, la primera petición abierta con parámetros con forma de anuncio no encontró archivo de caché y se generó desde cero en 0,341–0,369 segundos, y en el mismo segundo apareció el archivo de caché de la dirección sin parámetros.
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.025379Las tres veces siguieron el mismo orden, y la petición sin parámetros que vino después respondió desde el nuevo archivo de caché en 0,023–0,025 segundos. Como la petición no venía de un móvil, solo se crearon los dos archivos para PC.
En las direcciones a las que enlazan tus anuncios, comprueba tú mismo si hay archivo de caché y cuándo se creó; si se crean copias móviles aparte, revisa a la vez los archivos para PC y para móvil.
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 -->En una respuesta servida desde un archivo de caché, el comentario final del HTML lleva tras [Debug: cached@] la hora en que se creó el archivo, en tiempo Unix. Si falta esta marca, esa respuesta la generó WordPress desde cero.
🔢 FAQ & contenido recomendado
















ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.