Mailing Black Friday: cómo evitar que WordPress se sature al enviar la campaña

Se acerca el Black Friday. Prepararás la oferta, la landing, el mailing, los anuncios y quizá incluso comprobarás que el servidor tenga recursos suficientes para soportar el pico de visitas.

Pero hay una comprobación muy sencilla que es fácil pasar por alto:

¿qué ocurre con la caché cuando alguien entra en la web desde un enlace del mailing?

Una web que funciona perfectamente cada día puede saturarse pocos minutos después de enviar una campaña de correo. Y no necesariamente porque hayan entrado miles de personas a la vez.

El problema pueden ser los parámetros que la herramienta de mailing añade a los enlaces.

Según cómo esté configurada la caché, una URL con estos parámetros puede dejar de servirse desde la caché o generar una variante diferente. Si, además, la herramienta añade un identificador único para cada suscriptor, puedes acabar convirtiendo unas decenas de visitas aparentemente inofensivas en unas decenas de peticiones dinámicas a WordPress.

Y eso, en un momento en el que muchas personas hacen clic a la vez, puede ser suficiente para saturar un alojamiento.

En un caso reciente, solo 22 clics por minuto fueron suficientes para provocar problemas en la web.

El problema puede ser invisible antes de enviar

Esta es probablemente la parte más engañosa.

Entras en la landing antes de enviar el correo, compruebas que todo funciona, la página carga en una fracción de segundo y das el visto bueno.

Pero estás probando una URL limpia:

https://exemple.cat/oferta-black-friday/

Cuando se envía el mailing, el suscriptor puede llegar a una dirección como esta:

https://exemple.cat/oferta-black-friday/?utm_source=newsletter&utm_campaign=blackfriday&_mrSubscriber=123456

Y otra persona puede llegar a:

https://exemple.cat/oferta-black-friday/?utm_source=newsletter&utm_campaign=blackfriday&_mrSubscriber=789012

Para una persona son exactamente la misma página.

Para la caché, dependiendo de la configuración, pueden no serlo.

Cada suscriptor puede llegar con una URL que la caché no reconoce como la página que ya tenía guardada.

¿Por qué es tan importante la caché?

La mayoría de webs WordPress utilizan algún sistema de memoria caché o cache.

Cuando una página ya se ha generado, el servidor puede guardar una copia estática. Cuando llega el siguiente visitante, en lugar de ejecutar WordPress, PHP y las consultas a la base de datos otra vez, puede devolver directamente esa copia.

Simplificando mucho:

Visitante
   ↓
Caché
   ↓
HTML ya generado

es mucho menos costoso para el servidor que:

Visitante
   ↓
PHP
   ↓
WordPress
   ↓
Plugins
   ↓
Base de datos
   ↓
HTML

Una web modesta puede atender muchas visitas simultáneas si la mayoría se sirven desde la caché.

La misma web puede empezar a sufrir con mucho menos tráfico si cada visita obliga a ejecutar WordPress entero.

¿Qué parámetros añaden las herramientas de mailing?

Las herramientas de mailing suelen añadir parámetros a los enlaces para medir las campañas.

Los más conocidos son los UTM de Google Analytics:

utm_source
utm_medium
utm_campaign
utm_content
utm_term
utm_id

Normalmente, estos valores son iguales para todos los destinatarios de una misma campaña.

El problema puede ser mayor cuando la plataforma añade también un identificador único para cada suscriptor.

Herramienta Parámetros propios Puede ser único por suscriptor
HubSpot _hsenc, _hsmi _hsenc
Mailchimp mc_cid, mc_eid mc_eid
Mailrelay _mrMailingList, _mrSubscriber _mrSubscriber
Klaviyo _kx _kx
ActiveCampaign vgo_ee vgo_ee
Brevo, MailerLite, Acumbamail Sobre todo utm_* Normalmente no

Los nombres pueden cambiar según la plataforma, la versión o la configuración.

Por eso nunca me fiaría solo de una lista encontrada en internet.

La prueba más fiable es enviarte un correo de prueba, hacer clic en el enlace y mirar la URL final.

Los UTM también pueden dar problemas

Que los UTM sean iguales para todo el mundo no significa que siempre sean inofensivos.

Si el sistema de caché está configurado para que cualquier URL con parámetros quede fuera de la caché, esto:

/oferta/

puede servirse desde la caché, mientras que esto:

/oferta/?utm_source=newsletter

puede obligar al servidor a generar la página de nuevo.

La diferencia es que un identificador único por suscriptor puede multiplicar aún más el problema, porque cada persona llega con una URL diferente.

Un caso real: solo 22 clics por minuto

Hace poco lo vi en una web que gestiono.

Después de enviar un mailing, el tráfico alcanzó un pico de solo 22 clics por minuto.

No parece una barbaridad.

Pero los enlaces llevaban un identificador diferente para cada suscriptor y las visitas no se estaban resolviendo correctamente desde la caché.

Muchas peticiones tenían que pasar por PHP y consultar la base de datos.

El resultado fue que el alojamiento se saturó y algunos visitantes empezaron a ver una página de error de la capa de CDN/Varnish.

Lo más desconcertante era que WordPress aparentemente no tenía ningún error grave.

En los registros de WordPress puede no haber ningún error fatal ni ningún aviso en debug.log.

WordPress no necesariamente «falla»: el servidor puede acabar agotando los procesos PHP disponibles —los workers— u otros recursos mientras genera repetidamente la misma página con parámetros diferentes.

La reacción habitual es pensar que «el servidor no aguanta», cuando el problema puede ser simplemente cómo se están tratando esos parámetros en la caché.

Y eso explica también por qué el problema puede pasar desapercibido durante años: mientras el alojamiento absorbe las peticiones dinámicas, aparentemente todo funciona. El problema aparece el día en que coinciden suficientes clics en muy poco tiempo.

Cómo comprobarlo antes de enviar

La prueba es bastante sencilla y no hace falta instalar ninguna herramienta especial.

Windows 10 y Windows 11 ya incorporan curl.

Abre Símbolo del sistema (CMD).

Primero comprueba la página sin parámetros:

curl.exe -s -D - -o NUL "https://exemple.cat/oferta-black-friday/"

Este comando hace una petición HTTP normal, descarta el contenido HTML y muestra solo las cabeceras de respuesta.

Repite exactamente el mismo comando:

curl.exe -s -D - -o NUL "https://exemple.cat/oferta-black-friday/"

La primera petición puede haber generado la página.

La segunda, si todo funciona correctamente, ya podría servirse desde la caché.

Ahora prueba la URL que llega desde el mailing:

curl.exe -s -D - -o NUL "https://exemple.cat/oferta-black-friday/?utm_source=newsletter&utm_campaign=blackfriday&_mrSubscriber=123456"

Vuelve a ejecutarla.

Y, por último, cambia solo el identificador del suscriptor:

curl.exe -s -D - -o NUL "https://exemple.cat/oferta-black-friday/?utm_source=newsletter&utm_campaign=blackfriday&_mrSubscriber=789012"

Esto simula otro suscriptor que hace clic en el mismo enlace por primera vez.

La pregunta es: cuando cambia el identificador del suscriptor, ¿el servidor sigue pudiendo devolver la misma página desde la caché o WordPress tiene que generarla de nuevo?

macOS y Linux

El comando es prácticamente igual. Solo hay que sustituir:

-o NUL

por:

-o /dev/null

¿Por qué no utilizo curl -I?

Es muy habitual encontrar ejemplos como este:

curl.exe -sI "https://exemple.cat/oferta-black-friday/"

Es más corto y en muchos servidores funcionará perfectamente.

Pero la opción -I hace una petición HTTP HEAD.

Un visitante normal que entra en la página hace una petición GET.

Algunos servidores, proxies, CDN o sistemas de caché pueden tratar HEAD y GET de forma diferente.

Por eso, para comprobar el comportamiento real antes de un envío importante, prefiero:

curl.exe -s -D - -o NUL "URL"

La petición es GET, pero descartamos el cuerpo de la página y solo nos quedamos con las cabeceras.

¿Qué debes mirar en las cabeceras?

Depende del sistema de caché.

LiteSpeed

x-litespeed-cache: miss

y después:

x-litespeed-cache: hit

Cloudflare

cf-cache-status: MISS

o:

cf-cache-status: HIT

Varnish o CDN

Puedes encontrar una cabecera Age:

Age: 0

y, en una respuesta ya guardada:

Age: 125

Pero no todos los sistemas te ofrecen un HIT o un MISS tan fácil de interpretar.

El caso de W3 Total Cache con Disk: Enhanced

Con W3 Total Cache en modo Disk: Enhanced puede que no encuentres ninguna cabecera explícita que indique si la página se ha servido desde la caché.

En ese caso hay que comparar otras señales.

Una página servida desde la caché puede mostrar una cabecera como:

Last-Modified: Sat, 26 Sep 2026 12:02:47 GMT

con una hora anterior, y no mostrar:

X-Powered-By: PHP/...

En cambio, cuando la petición ha tenido que pasar por PHP puede aparecer:

X-Powered-By: PHP/8.3

o la versión correspondiente.

No es una regla universal para cualquier servidor, pero sí una pista muy útil cuando comparas dos respuestas de la misma web.

Lo importante no es buscar obsesivamente la palabra HIT.

Lo importante es comparar qué ocurre con:

/pagina/

y con:

/pagina/?parametre=valor

Cuidado: puedes tener dos cachés a la vez

Este es otro punto que puede llevar a conclusiones equivocadas.

Una web puede tener una arquitectura como esta:

Visitante
   ↓
CDN / Varnish
   ↓
W3 Total Cache
   ↓
PHP + WordPress
   ↓
Base de datos

La CDN puede responder siempre:

Age: 0

o mostrar un MISS.

Pero eso no significa necesariamente que WordPress haya tenido que ejecutar PHP.

Puede ocurrir perfectamente que la CDN no guarde el HTML y que, en cambio, W3 Total Cache esté devolviendo un archivo estático.

Un MISS en la CDN no implica necesariamente un MISS en la caché de WordPress.

Hay que mirar las dos capas.

Por ejemplo, si tienes Age: 0, pero no aparece X-Powered-By: PHP y el Last-Modified corresponde a una copia anterior, es posible que la CDN no haya servido la página desde su caché pero W3 Total Cache sí.

La pregunta final siempre es la misma:

¿esta visita ha obligado a WordPress a ejecutar PHP o no?

Cómo solucionarlo

La solución habitual es configurar el sistema de caché para que determinados parámetros de seguimiento no obliguen a generar la página de nuevo.

Es decir, que:

/oferta-black-friday/

y:

/oferta-black-friday/?utm_source=newsletter&_mrSubscriber=123456

puedan aprovechar la misma copia de la página.

Los parámetros siguen existiendo en la URL del navegador. Por tanto, Google Analytics y las herramientas de mailing pueden seguir utilizándolos.

Lo que hacemos es evitar que unos parámetros que solo sirven para hacer seguimiento obliguen a WordPress a generar de nuevo el mismo contenido.

Sistema Dónde revisarlo
W3 Total Cache Performance → Page Cache → Advanced → Accepted query strings
LiteSpeed Cache Cache → Advanced → Drop Query String
WP Rocket Ignora muchos parámetros de seguimiento habituales por defecto; hay que revisar los que no reconozca
Cloudflare Revisar las reglas de caché y la clave de caché
Varnish o CDN del alojamiento Comprobar con el proveedor cómo trata los query strings

Parámetros que suelo revisar

utm_source
utm_medium
utm_campaign
utm_content
utm_term
utm_id
fbclid
gclid
msclkid
_hsenc
_hsmi
mc_cid
mc_eid
_mrSubscriber
_mrMailingList
_kx
vgo_ee

No copiaría esta lista a ciegas.

El procedimiento correcto es:

  1. Enviarte un correo de prueba.
  2. Hacer clic en el enlace.
  3. Copiar la URL completa.
  4. Identificar qué parámetros hay.
  5. Comprobar cuáles modifican el contenido y cuáles solo sirven para hacer seguimiento.
  6. Configurar solo estos últimos para que no afecten a la caché.

No ignores todos los parámetros

Puede parecer tentador decirle a la caché: «ignora todo lo que haya después del ?».

No lo hagas sin saber cómo funciona la web.

Hay páginas que dependen precisamente de los parámetros.

Por ejemplo, la búsqueda de WordPress utiliza:

?s=paraula

Una tienda puede utilizar parámetros para filtrar productos.

Una galería puede utilizarlos para la paginación.

Un buscador, configurador o comparador puede necesitarlos para mostrar contenido diferente.

Si ignoras todos los parámetros indiscriminadamente, puedes acabar sirviendo el mismo contenido en URL que deberían mostrar resultados diferentes.

Ignora solo los parámetros que sabes que son de seguimiento y que no modifican el contenido de la página.

Vigila también los UTM duplicados

Durante esta revisión es habitual descubrir otro problema.

Algunas plataformas de mailing pueden añadir automáticamente los UTM de Google Analytics.

Si tú ya los habías añadido manualmente, puedes acabar con una URL como:

?utm_source=newsletter&utm_campaign=blackfriday&utm_source=mailing&utm_campaign=campanya123

Esto no suele provocar el mismo problema de rendimiento que una caché mal configurada.

Pero sí puede ensuciar los datos de Analytics y fragmentar una misma campaña bajo nombres diferentes.

Por tanto, comprueba siempre quién añade los UTM:

o tú o la herramienta de mailing, pero preferiblemente no los dos.

Antes de pulsar «Enviar»

  • He enviado un correo de prueba desde la plataforma real.
  • He hecho clic en uno de los enlaces.
  • He mirado la URL final completa.
  • Sé qué parámetros añade la plataforma.
  • He comprobado la página sin parámetros con curl.
  • He repetido la prueba con los parámetros del mailing.
  • He cambiado el identificador del suscriptor para simular una nueva visita.
  • He comprobado si hay una o más capas de caché.
  • He verificado que los parámetros de seguimiento no obliguen a WordPress a ejecutar PHP de nuevo.
  • No he configurado la caché para que ignore indiscriminadamente todos los parámetros.
  • He comprobado que los UTM no estén duplicados.
  • Después de los últimos cambios he vaciado la caché.
  • He vuelto a abrir las páginas de destino para que vuelvan a quedar preparadas en la caché.
  • He repetido la prueba final.

Una web puede soportar muchas visitas cuando sirve páginas desde la caché y empezar a sufrir con unas pocas decenas cuando todas obligan a WordPress a ejecutar PHP.

Por eso, antes de un Black Friday, unas rebajas, una venta de entradas, la apertura de inscripciones o cualquier mailing que pueda concentrar muchas visitas en pocos minutos, merece la pena dedicar cinco minutos a comprobarlo.

Puede evitar que la web falle precisamente en el momento en el que más visitas te interesa recibir.

Si estás preparando una campaña importante y no tienes claro cómo responderá WordPress cuando lleguen muchas visitas a la vez, esta es una de las comprobaciones que merece la pena hacer antes de pulsar «Enviar».