La forma más rápida de perder una mañana es “acelerar WordPress” activando un caché agresivo en el borde, y luego descubrir
que tus editores no pueden iniciar sesión, las vistas previas muestran contenido antiguo y wp-admin carga como si caminara en miel. La forma más rápida
de perder una tarde es arreglarlo purgando todo cada cinco minutos hasta que el sitio “se sienta bien”.
Puedes tener velocidad y una experiencia de administración sensata. Pero necesitas reglas de caché que respeten cómo WordPress usa cookies, nonces
y respuestas personalizadas. Este es el manual que uso en producción: qué cachear, qué nunca cachear, cómo demostrarlo,
y cómo diagnosticar las fallas raras que solo aparecen cuando el CEO está viendo una demo.
Las pocas reglas que importan
El caché en el borde es una herramienta tosca. WordPress es una máquina sutil construida sobre cookies, estado de usuario y nonces con límite temporal
que protegen formularios y acciones. Si cacheas la respuesta equivocada, no solo sirves HTML obsoleto: sirves el HTML equivocado
a la persona equivocada, y WordPress se da cuenta. A menudo de forma ruidosa.
Regla 1: Nunca cachear respuestas autenticadas o con estado
En la práctica, “autenticado” significa “tiene cookies de autenticación de WordPress” y “con estado” significa “cookies de carrito/checkout/sesión” o
páginas que incluyen nonces. Si una petición lleva cookies que cambian lo que el origen devolvería, debes evitar el caché.
Aun así puedes cachear activos estáticos para usuarios autenticados; solo no cachees HTML.
Regla 2: Cachea HTML público solo cuando puedas probar que es público
“Cache Everything” está bien si lo combinas con reglas fuertes de bypass basadas en cookies y rutas. Sin reglas de bypass es
cómo terminas cacheando respuestas de /wp-admin/ y sirviéndolas a la siguiente persona que pregunte. Sí, esto pasa. No, no es
divertido. Tu modelo de amenaza debe incluir a la “caché bienintencionada” como un adversario.
Regla 3: Usa pocas reglas claras y luego observa
No construyas una catedral de 47 reglas en el borde el primer día. Empieza con: (1) bypass admin/login, (2) bypass cuando cookies indican
sesión o autenticación, (3) cachea activos estáticos agresivamente, (4) cachea HTML público con un TTL razonable y un plan de purga.
Luego mide tasa de aciertos y carga del origen.
Regla 4: Si no puedes explicar una decisión de caché, no puedes operarla
Cada comportamiento de caché debe mapearse a una señal observable: un encabezado (CF-Cache-Status), una línea de logs, una cookie o una coincidencia de ruta.
Si la única forma de “debuggear” es hacer clic en actualizar y esperar, no estás ejecutando un caché. Estás ejecutando una máquina tragaperras.
Broma #1: El caché es fácil hasta que no lo es—como DNS, pero con más oportunidades para que tu propio sitio te vuelva loco.
Hechos interesantes y breve historia
- Hecho 1: Los nonces de WordPress no son nonces criptográficos verdaderos; son tokens basados en tiempo diseñados para protección CSRF con ventana de validez.
- Hecho 2: La cookie
wordpress_logged_in_es la señal más simple y fiable de que una petición no debe servirse desde caché público. - Hecho 3: Muchos plugins de WordPress añaden sus propias cookies (tests A/B, banners de consentimiento, analíticas). Algunas son inofensivas; otras cambian la salida de la página.
- Hecho 4: “Cache Everything” en Cloudflare se popularizó originalmente como solución para cachear HTML en sitios que no tienen un proxy inverso como Varnish.
- Hecho 5: La constante de WordPress
DONOTCACHEPAGEexiste porque incluso los caches del lado servidor no pueden adivinar de forma segura cuándo una página está personalizada. - Hecho 6: El borde de Cloudflare respeta ciertos encabezados de caché, pero “respetar” y “hacer exactamente lo que crees” no son lo mismo a menos que lo pruebes.
- Hecho 7: Un número sorprendente de incidentes de “wp-admin lento” son en realidad contención de CPU en el origen por workers PHP, no latencia de red.
- Hecho 8: Purgar es costoso operativamente. Incluso cuando es “instantáneo”, puede colapsar tu ratio de aciertos e inundar tu origen.
- Hecho 9: Los fragmentos de carrito de WooCommerce (históricamente vía
?wc-ajax=get_refreshed_fragments) son una fuente recurrente de confusión de caché y personalización parcial.
Qué significa realmente “no romper wp-admin”
El listón no es “wp-admin carga”. El listón es: el inicio de sesión funciona, las acciones protegidas por nonce funcionan, los redireccionamientos no hacen bucles, las vistas previas muestran
el contenido actual, las subidas de medios tienen éxito, los editores no ven sesiones de otros usuarios y tu caché no filtra datos privados.
Ese es el mínimo viable de seguridad.
Esto es lo que comúnmente se rompe cuando las reglas de caché son descuidadas:
- Bucle de redirección de login: las publicaciones en /wp-login.php establecen cookies, luego el borde sirve una respuesta cacheada que ignora el nuevo estado de cookie.
- UI de admin obsoleta: caché de
/wp-admin/o de respuestas admin-ajax. Un “No tienes permiso” cacheado puede arruinar una hora. - Problemas en vista previa y editor: los enlaces de vista previa incluyen parámetros tipo nonce; cachear esos resulta en mostrar el borrador de ayer como “actual”.
- Filtración de la barra de administración personalizada: cachear páginas públicas sin tener en cuenta que los usuarios conectados reciben la barra de administración inyectada.
- Problemas con el carrito de WooCommerce: cachear carrito/checkout o endpoints de fragmentos produce carritos fantasma y tickets de soporte.
Si tu configuración de caché no puede expresar “cachear esto solo cuando no hay cookies de estado presentes”, no estás listo para cachear HTML.
Afortunadamente, Cloudflare puede expresarlo—solo tienes que hacerlo deliberadamente.
Ajustes base de Cloudflare para WordPress (predeterminados seguros)
La base limpia es: cachear activos estáticos fuertemente, no cachear admin o login, y cachear HTML público solo si tienes reglas de bypass por cookie. Todo lo demás es adorno.
1) Cachear activos estáticos agresivamente
Estos son seguros para cachear en el borde incluso para usuarios autenticados porque no varían por usuario (a menos que estés haciendo algo
muy creativo con CSS, lo cual es otra discusión y posiblemente un grito de ayuda).
- Imágenes:
.png .jpg .jpeg .gif .webp .svg - CSS/JS:
.css .js - Fuentes:
.woff .woff2 .ttf .otf
Usa TTL largos en el navegador con nombres de archivos versionados. El core de WordPress y muchos temas ya agregan query strings; mejor son nombres hashados,
pero no dejes que lo perfecto impida el progreso. Si no puedes fingerprintear activos, mantén TTL del navegador moderado y confía en el borde.
2) Bypassear caché para rutas de admin y login
Esto es innegociable:
/wp-admin/*/wp-login.php/wp-json/*(al menos para contextos autenticados; endpoints públicos se pueden cachear caso a caso)/xmlrpc.php(idealmente bloquear si no se usa; si se usa, no cachear)/wp-admin/admin-ajax.php(no cachear)
3) Bypassear caché cuando existan ciertas cookies
El borde de Cloudflare no puede “entender” WordPress, pero puede hacer coincidir cookies. Estas son las importantes:
wordpress_logged_in_*→ usuario autenticadowordpress_sec_*→ autenticación en áreas admin sobre SSLwp-postpass_*→ entradas protegidas por contraseña- Cookies de WooCommerce:
woocommerce_items_in_cart,woocommerce_cart_hash,wp_woocommerce_session_* - Algunos plugins de membresía establecen sus propias cookies; identifícalas e inclúyelas
4) Decide qué harás con el HTML
Tienes dos opciones sensatas:
- Conservadora: No cachear HTML en Cloudflare en absoluto. Cachear solo activos estáticos. Usar un caché en origen (plugin, Nginx FastCGI cache o un proxy inverso) para HTML. Esta es la opción “quiero comportamiento predecible”.
- Cacheo de HTML en el borde: Cachear HTML público en Cloudflare con reglas estrictas de bypass. Esta es la opción “quiero máximo alivio al origen y velocidad global”.
Lo que evito: cachear HTML a veces, pero sin una política clara. Así es como obtienes un sitio que es rápido para ti y roto para todos los demás.
Estrategia de caché: estático, HTML y el peligroso término medio
Activos estáticos: aburrido, correcto y rentable
El caché estático es donde Cloudflare brilla con bajo riesgo. Si tu origen está con problemas, empieza por aquí. Reducirás ancho de banda,
disminuirás handshakes TLS en tu servidor y obtendrás mejor rendimiento en picos de tráfico.
HTML: vale la pena, pero solo con guardarraíles
Cachear HTML en el borde puede convertir un VPS de $20 en algo que sobrevive al front page de internet—hasta que sirve el HTML equivocado
al usuario equivocado. La única manera segura es asegurar que la variante cacheada represente la misma respuesta que tu origen devolvería
para todos los usuarios en ese bucket de caché.
Para la mayoría de sitios WordPress, el bucket seguro es “sin cookie de login y sin cookie de sesión/carrito”. Ese es tu caché público.
Todo lo demás debe bypassearse.
El peligroso término medio: endpoints que parecen estáticos pero no lo son
Estos son los sutiles:
- Páginas de búsqueda: muchas variantes, a veces personalizadas; el cacheo puede funcionar pero necesita keying cuidadoso y TTL corto.
- Feeds: se pueden cachear, pero a los editores les molestan los feeds obsoletos; mantén TTL corto.
- REST API: endpoints públicos se pueden cachear, endpoints autenticados no.
- Contenido localizado o A/B: si el contenido varía por cookie u encabezado, la clave del caché debe incluirlo o debes bypassear.
Si no estás seguro, bypassea. Rápido y equivocado sigue siendo equivocado, solo con mejores tiempos de ping.
Reglas de no-cache para wp-admin, login y vistas previas
Rutas que siempre deben bypassear el caché
Si implementas solo una cosa, implementa esta lista. Puedes traducirla a Cloudflare Cache Rules (preferido), Page
Rules antiguas (legado) o un Worker.
*example.com/wp-admin/*→ Bypass cache*example.com/wp-login.php*→ Bypass cache*example.com/wp-admin/admin-ajax.php*→ Bypass cache*example.com/wp-cron.php*→ Bypass cache (o limitar por tasa; no cachear)*example.com/?preview=true*→ Bypass cache*example.com/*preview_id=*and*preview_nonce=*Bypass cache
Desactiva “mejoras” de rendimiento para rutas admin
Algunas optimizaciones son geniales para tráfico anónimo y molestas para usuarios autenticados. Para rutas admin y login,
me gusta la opción aburrida:
- Desactiva la minificación HTML si alguna vez ha roto tu UI de admin (pasa con plugins raros).
- Sé cauto con reescrituras JS tipo Rocket Loader. El admin carga muchos scripts; no necesitas magia en el borde allí.
- Mantén las funciones de seguridad (WAF) activadas, pero prueba que no desafíen a los admins en medio de acciones.
WooCommerce y otras páginas personalizadas
WooCommerce añade sesiones de cliente, estado de carrito y flujos de checkout que son alérgicos al cacheo incorrecto. Aun así puedes
cachear páginas de producto y listados de categoría para usuarios anónimos—con grandes ganancias—pero debes excluir las rutas transaccionales.
Siempre bypassear el caché para estas rutas de WooCommerce
/cart/*/checkout/*/my-account/*/?wc-ajax=*- Cualquier endpoint “add-to-cart” o parámetro de consulta que use tu tema
Bypassear en estas cookies de WooCommerce
woocommerce_items_in_cartwoocommerce_cart_hashwp_woocommerce_session_*
Qué cachear con seguridad en WooCommerce
Páginas públicas de producto, listados de categoría, imágenes estáticas, CSS/JS. Mantén TTL razonable (minutos a una hora) a menos que tengas
integración de purga fuerte cuando cambie inventario/precios.
Broma #2: Si cacheas la página de checkout, no has construido un sitio ecommerce—has construido un juego de adivinanzas interactivo.
Encabezados de origen: Cache-Control, Vary y por qué importan
La política de caché de Cloudflare es una conversación entre tu origen, las configuraciones de Cloudflare y la petición. Si solo controlas
un lado de esa conversación, vas a malinterpretar el resultado.
Cache-Control: la intención de tu origen
Para contenido admin y personalizado, quieres:
Cache-Control: private, no-storeono-cachedependiendo de tu stack
Para HTML público que estés dispuesto a cachear:
Cache-Control: public, max-age=0, s-maxage=...(si quieres que el borde cachee más tiempo que los navegadores)- O deja que Cloudflare establezca un Edge TTL y mantén un TTL moderado en el navegador
Vary: el multiplicador silencioso de la clave de caché
Vary indica a los caches qué encabezados de petición afectan la respuesta. Si tu origen envía Vary: Cookie,
efectivamente haces que cada combinación de cookies sea un objeto diferente. Eso puede ser correcto para respuestas personalizadas, y
catastrófico para el rendimiento si se filtra en páginas públicas.
Prefiere evitar Vary: Cookie en HTML público bypasseando según cookies en su lugar. Si un plugin lo fuerza,
puede que necesites desactivar ese comportamiento o aceptar una tasa de aciertos menor.
Una cita con la que realmente puedes operar un sistema
Werner Vogels (idea parafraseada): “Todo falla, todo el tiempo—diseña para que los sistemas sigan funcionando igualmente.” Eso también aplica al caché:
asume fallos parciales y objetos obsoletos, luego contiene el radio de daño.
Tareas prácticas: comandos, salidas, decisiones (12+)
Estos son los chequeos que ejecuto cuando alguien dice “Cloudflare caching rompió wp-admin” o “habilitamos caché y ahora las cosas están raras.”
Cada tarea incluye un comando, salida de ejemplo, qué significa y qué decisión tomar a partir de ello.
Task 1: Confirmar si Cloudflare está cacheando una página pública
cr0x@server:~$ curl -sI https://example.com/ | egrep -i 'cf-cache-status|cache-control|age|server'
server: cloudflare
cf-cache-status: HIT
age: 842
cache-control: max-age=0, s-maxage=3600
Significado: La respuesta la sirvió Cloudflare (server: cloudflare) y es un HIT de caché con edad de objeto de 842 segundos.
Decisión: El cacheo de HTML público está activo. A continuación, verifica que el bypass por cookie funcione para sesiones autenticadas.
Task 2: Verificar que wp-admin no esté cacheado (debe ser BYPASS o DYNAMIC)
cr0x@server:~$ curl -sI https://example.com/wp-admin/ | egrep -i 'cf-cache-status|location|set-cookie|cache-control'
cf-cache-status: DYNAMIC
cache-control: no-store, no-cache, must-revalidate, max-age=0
Significado: Cloudflare no sirvió esto desde caché. El origen está señalando no-store/no-cache.
Decisión: El bypass por ruta funciona para /wp-admin/. Si los administradores aún tienen problemas, revisa cookies, desafíos del WAF o rendimiento del origen.
Task 3: Verificar que wp-login.php no esté cacheado
cr0x@server:~$ curl -sI https://example.com/wp-login.php | egrep -i 'cf-cache-status|cache-control|set-cookie'
cf-cache-status: DYNAMIC
cache-control: no-store, no-cache, must-revalidate, max-age=0
Significado: El login no está cacheado. Bien.
Decisión: Si los bucles de login siguen ocurriendo, probablemente tengas un problema de cookie/redirección o configuraciones HTTP/HTTPS mixtas en WordPress/Cloudflare.
Task 4: Simular una cookie de sesión y asegurar que las páginas públicas bypasseen
cr0x@server:~$ curl -sI https://example.com/ -H 'Cookie: wordpress_logged_in_abc=1' | egrep -i 'cf-cache-status|cache-control|age'
cf-cache-status: BYPASS
cache-control: private, no-cache, no-store, must-revalidate
Significado: Tu regla de bypass por cookie es efectiva; Cloudflare no está cacheando HTML cuando existe la cookie de login.
Decisión: Seguro para usuarios autenticados. Si ves HIT aquí, detente y arregla las reglas antes de filtrar contenido personalizado.
Task 5: Revisar comportamiento de caché de la REST API (endpoint público)
cr0x@server:~$ curl -sI https://example.com/wp-json/ | egrep -i 'cf-cache-status|cache-control|content-type'
content-type: application/json; charset=UTF-8
cf-cache-status: DYNAMIC
cache-control: no-cache, must-revalidate, max-age=0
Significado: La raíz de REST es dinámica y no está cacheada.
Decisión: Manténla dinámica a menos que tengas una razón específica para cachear ciertos endpoints públicos con TTL corto y una estrategia clara de invalidación.
Task 6: Detectar caché accidental de vistas previas (fallo clásico)
cr0x@server:~$ curl -sI "https://example.com/?p=123&preview=true" | egrep -i 'cf-cache-status|cache-control|age'
cf-cache-status: DYNAMIC
cache-control: private, no-cache, no-store, must-revalidate
Significado: Las respuestas de vista previa no están cacheadas.
Decisión: Si esto es HIT, añade reglas de bypass para parámetros de preview inmediatamente.
Task 7: Confirmar que admin-ajax no esté cacheado
cr0x@server:~$ curl -sI https://example.com/wp-admin/admin-ajax.php | egrep -i 'cf-cache-status|cache-control'
cf-cache-status: DYNAMIC
cache-control: no-store, no-cache, must-revalidate, max-age=0
Significado: Bien. Cachear admin-ajax rompe partes aleatorias de la UI admin y funcionalidades del front-end.
Decisión: Si no es dinámico, bypassea esa ruta y considera añadir una regla WAF en lugar de cachearla.
Task 8: Inspeccionar cookies de WordPress desde la página de login
cr0x@server:~$ curl -sI https://example.com/wp-login.php | egrep -i 'set-cookie|location'
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/; secure; HttpOnly; SameSite=Lax
Significado: WordPress está estableciendo una cookie de prueba; el flujo de login depende de la aceptación de cookies.
Decisión: Si las cookies faltan o se alteran, revisa Transform Rules/Workers de Cloudflare, encabezados de seguridad o un plugin que interfiera con cookies.
Task 9: Verificar corrección HTTPS y cadena de redirecciones
cr0x@server:~$ curl -sI http://example.com/wp-admin/ | egrep -i 'HTTP/|location|server'
HTTP/1.1 301 Moved Permanently
server: cloudflare
location: https://example.com/wp-admin/
Significado: HTTP redirige correctamente a HTTPS.
Decisión: Si ves bucles (http→https→http), arregla el modo SSL (usualmente Full/Strict) y asegúrate de que “Site URL” y “Home” en WordPress estén en HTTPS.
Task 10: Comprobar si Cloudflare está sirviendo HTML cacheado a una petición con cookies WooCommerce
cr0x@server:~$ curl -sI https://example.com/product/widget/ -H 'Cookie: wp_woocommerce_session_123=1; woocommerce_items_in_cart=1' | egrep -i 'cf-cache-status|age'
cf-cache-status: BYPASS
Significado: Comportamiento correcto: no cachear HTML con estado de sesión/carrito de WooCommerce.
Decisión: Si ves HIT, añade reglas de bypass por cookie y excluye rutas transaccionales inmediatamente.
Task 11: Validar encabezados de respuesta directamente desde el origen (saltando Cloudflare)
cr0x@server:~$ curl -sI https://origin.example.internal/ | egrep -i 'cache-control|vary|set-cookie|server'
server: nginx
cache-control: public, max-age=0, s-maxage=600
vary: Accept-Encoding
Significado: El origen pretende cacheo en el borde por 600 segundos y no varía por Cookie. Eso es bueno para páginas públicas.
Decisión: Alinea Edge TTL de Cloudflare con la intención del origen, o sobrescribe con cuidado. Si ves Vary: Cookie, espera dolor en la tasa de aciertos.
Task 12: Buscar cookies sorprendentes en peticiones anónimas
cr0x@server:~$ curl -sI https://example.com/ | egrep -i 'set-cookie'
set-cookie: pll_language=en; path=/; secure; SameSite=Lax
Significado: Un plugin de idioma establece una cookie incluso para usuarios anónimos. Eso puede o no cambiar el HTML.
Decisión: Si el contenido varía por esa cookie, o bien varía el caché por ella (con cuidado) o bypassea para esos usuarios; si no, ignórala para mantener alta la tasa de aciertos.
Task 13: Confirmar que una purga realmente cambia el objeto (detectar contenido obsoleto)
cr0x@server:~$ curl -sI https://example.com/ | egrep -i 'cf-cache-status|age|etag|last-modified'
cf-cache-status: HIT
age: 3599
etag: "a1b2c3"
Significado: El objeto en el borde tiene casi una hora.
Decisión: Si acabas de actualizar contenido y esperabas el cambio, necesitas o (a) mejores triggers de purga, (b) TTL más corto para HTML, o (c) cache-busting vía claves/surrogate tags (si tu setup lo soporta).
Task 14: Revisar salud y latencia del origen cuando el caché se bypassea
cr0x@server:~$ curl -s -o /dev/null -w 'ttfb=%{time_starttransfer} total=%{time_total}\n' https://example.com/wp-admin/
ttfb=1.842 total=1.913
Significado: Time-to-first-byte es ~1.8s para admin. Eso es tiempo del origen/PHP/DB, no de Cloudflare.
Decisión: Deja de obsesionarte con el caché en el borde y perfila workers PHP, consultas de base de datos y el caché de objetos. La velocidad del admin depende del origen.
Task 15: Inspeccionar presión de PHP-FPM (lentitud común en wp-admin)
cr0x@server:~$ sudo ss -s
Total: 256 (kernel 0)
TCP: 128 (estab 22, closed 84, orphaned 0, synrecv 0, timewait 84/0), ports 0
Transport Total IP IPv6
RAW 0 0 0
UDP 6 4 2
TCP 44 28 16
INET 50 32 18
FRAG 0 0 0
Significado: Esto no muestra directamente PHP-FPM, pero sí muestra churn de conexiones. Contrástalo con el estado de PHP-FPM o conteos de procesos.
Decisión: Si el admin está lento durante tráfico alto y las rutas bypasseadas se acumulan, aumenta capacidad de PHP-FPM o reduce plugins costosos en admin en lugar de tocar TTL en el borde.
Task 16: Revisar logs de acceso de Nginx para endpoints bypasseados que reciben demasiado tráfico
cr0x@server:~$ sudo tail -n 5 /var/log/nginx/access.log
203.0.113.10 - - [27/Dec/2025:10:14:01 +0000] "POST /wp-login.php HTTP/2.0" 200 4578 "-" "Mozilla/5.0"
203.0.113.11 - - [27/Dec/2025:10:14:02 +0000] "GET /wp-admin/admin-ajax.php?action=heartbeat HTTP/2.0" 200 321 "-" "Mozilla/5.0"
203.0.113.12 - - [27/Dec/2025:10:14:02 +0000] "GET /wp-admin/admin-ajax.php?action=heartbeat HTTP/2.0" 200 321 "-" "Mozilla/5.0"
203.0.113.13 - - [27/Dec/2025:10:14:03 +0000] "GET /wp-admin/admin-ajax.php?action=heartbeat HTTP/2.0" 200 321 "-" "Mozilla/5.0"
203.0.113.14 - - [27/Dec/2025:10:14:03 +0000] "GET /wp-admin/admin-ajax.php?action=heartbeat HTTP/2.0" 200 321 "-" "Mozilla/5.0"
Significado: Las llamadas heartbeat pueden acumularse con muchos editores e inflar la carga de PHP. Cachear no ayudará porque no debe cachearse.
Decisión: Ajusta la frecuencia de Heartbeat, reduce editores concurrentes o escala workers PHP. Considera limitar por tasa patrones abusivos en el borde.
Guion de diagnóstico rápido
Cuando estás en el apuro y alguien grita “Cloudflare lo hizo”, necesitas un camino corto hacia la verdad. Este es mi flujo de
comprobar-primero/segundo/tercero.
Primero: ¿La respuesta mala está cacheada?
- Revisa
CF-Cache-Statusen la URL que falla. - Si es
HIToSTALEen una URL de admin/login/preview, ya encontraste el problema: tus reglas de bypass están mal. - Si es
DYNAMICoBYPASS, el caché de Cloudflare probablemente no sea la causa directa. Sigue con lo siguiente.
Segundo: ¿La petición tiene estado (cookies) y olvidaste bypassear?
- Repite la petición con una cookie simulada
wordpress_logged_in_*y asegúrate de que haga bypass. - Para WooCommerce, prueba con cookies de carrito/sesión.
- Si las peticiones con cookies se cachean, detente. Arregla el bypass por cookie y purga el HTML afectado.
Tercero: ¿Es un desajuste de redirección/modo SSL?
- Revisa la cadena de redirecciones HTTP a HTTPS y de www a apex (o viceversa).
- Confirma que “Home URL” y “Site URL” en WordPress coinciden con lo que Cloudflare sirve.
- El modo SSL de Cloudflare debe ser Full (Strict) si tu origen tiene un certificado válido.
Cuarto: ¿Es en realidad rendimiento del origen?
- Mide TTFB para
/wp-admin/y otros endpoints bypasseados. - Si TTFB es alto, optimiza PHP/DB/caché de objetos. El admin nunca será rápido si el origen está sobrecargado.
Quinto: ¿Es una función de seguridad interfiriendo (WAF / bot fight / challenges)?
- Busca 403/429/desafíos JS durante acciones en admin.
- Allowliste IPs de oficina o aplica SSO/VPN para admin, en lugar de desactivar protección globalmente.
Errores comunes: síntoma → causa raíz → solución
1) Síntoma: wp-admin muestra un “Por favor inicia sesión” cacheado incluso después de iniciar sesión
Causa raíz: /wp-admin/ o /wp-login.php se cachearon vía “Cache Everything” sin bypass.
Solución: Añade reglas de bypass explícitas para /wp-admin/*, /wp-login.php, y purga caché. Verifica con CF-Cache-Status: DYNAMIC.
2) Síntoma: Bucle de redirección en login (wp-login.php → wp-admin → wp-login.php)
Causa raíz: Esquema mixto (HTTP/HTTPS) o modo SSL incorrecto; cookies establecidas para HTTPS pero las peticiones rebotan por HTTP, o el origen piensa que está en HTTP detrás de proxy.
Solución: Asegura que Cloudflare esté en Full (Strict) hacia el origen, fuerza HTTPS, configura URLs de WordPress a HTTPS y asegúrate que el origen vea correctamente X-Forwarded-Proto / CF-Visitor.
3) Síntoma: La vista previa muestra contenido antiguo o el borrador de otra persona
Causa raíz: Las URLs de preview se cachearon en el borde. Los parámetros de preview no están excluidos.
Solución: Bypassea cache para preview=true, preview_id, preview_nonce y considera bypassear por cookies de usuarios logueados por completo.
4) Síntoma: El carrito de WooCommerce muestra artículos equivocados o se vacía aleatoriamente
Causa raíz: Páginas de carrito/checkout cacheadas o endpoints de fragmentos cacheados. O falta de bypass por cookie.
Solución: Bypassea caché para rutas cart/checkout/my-account, bypass por cookies de sesión/carrito de WooCommerce y no cachees ?wc-ajax=*.
5) Síntoma: Usuarios logueados ven la barra de administración ausente o medio rota
Causa raíz: HTML cacheado para usuarios logueados, o optimizaciones de borde reescribiendo JS/CSS en admin/front-end para sesiones autenticadas.
Solución: Bypassea caché HTML para wordpress_logged_in_*. Desactiva optimizaciones de scripts riesgosas en rutas admin/login.
6) Síntoma: 403 aleatorios en wp-admin, especialmente al guardar/publicar
Causa raíz: Una regla del WAF coincide con POSTs admin, o protecciones contra bots desafían acciones autenticadas.
Solución: Crea excepciones WAF dirigidas para endpoints admin autenticados, mantiene protección para tráfico anónimo y valida que no se cacheen páginas que recibieron desafíos.
7) Síntoma: El sitio es rápido para usuarios anónimos, pero wp-admin es dolorosamente lento
Causa raíz: Eso es normal si el origen está sobrecargado. El admin no puede cachearse de forma segura, así que expone lentitud de PHP/DB.
Solución: Añade caché de objetos, ajusta PHP-FPM, reduce plugins pesados en admin, optimiza la base de datos y considera escalar el origen. No intentes “cachear wp-admin.”
8) Síntoma: Purga “lo arregla” pero solo por unos minutos
Causa raíz: Estás enmascarando una política de caché incorrecta; contenido se está cacheando cuando no debería, o TTL es demasiado largo sin integración de purga.
Solución: Arregla reglas de bypass, corrige TTLs e implementa purgas dirigidas en publish/update. Purgar como mecanismo de afrontamiento no es una estrategia.
Tres micro-historias del mundo corporativo
Historia 1: Un incidente causado por una suposición equivocada
Una empresa mediana tuvo un sitio de marketing WordPress detrás de Cloudflare. Un ingeniero bienintencionado vio CPU alta en el origen durante una
campaña y habilitó “Cache Everything” para toda la zona, pensando que WordPress “sabría” no cachear páginas admin.
Asumieron que los encabezados Cache-Control del origen los protegerían en todas partes.
Durante una hora todo se vio bien—TTFB bajó, la carga de origen se aplanó, los dashboards festejaron. Luego los editores reportaron
que estaban “deslogueados aleatoriamente.” Minutos después, alguien dijo en el canal de incidentes que wp-admin a veces cargaba
pero mostraba la pantalla de otra persona. No fue fuga de contenido, por suerte, pero sí suficiente para desencadenar una auditoría de pánico.
La causa raíz fue mundana: una sola regla amplia aplicada a /* sin bypass explícito para /wp-admin/
y /wp-login.php. Algunas respuestas admin tenían códigos cacheables y se almacenaron lo suficiente para crear un
carrusel de confusión. El origen enviaba “no-store” la mayoría del tiempo, pero no consistentemente para cada caso borde y
respuesta de redirección en el flujo de login.
La solución también fue mundana: reglas explícitas de bypass para admin/login más bypass por cookie para sesiones logueadas. Luego una purga completa
de HTML. La solución a largo plazo fue cultural: ningún cambio de caché sin una validación rápida con curl de CF-Cache-Status
para admin, login, preview y una petición con cookie.
Historia 2: Una optimización que salió mal
Una organización mayor quería “paridad de rendimiento global” y decidió cachear HTML público en el borde con un TTL largo para reducir costos de origen.
Conectaron purgas programadas cada hora “por seguridad.” Sonaba razonable en una hoja de cálculo.
En producción, la purga horaria creó una estampida predecible al origen. Justo después de la purga, la tasa de aciertos colapsó,
cada página fue MISS, y el origen fue golpeado. El balanceador empezó a encolar, workers PHP se saturaron y wp-admin
se volvió inutilizable para editores precisamente durante los periodos en que los equipos de contenido eran más activos.
Para empeorar las cosas, algunas páginas estaban personalizadas por un plugin de consentimiento que inyectaba HTML ligeramente distinto según una
cookie. La clave de caché no variaba por esa cookie (porque variar por cookies habría destruido la tasa de aciertos), así que tras
cada purga, la variante que se cacheó primero era la que veían todos hasta que expiraba.
La solución final no fue espectacular. Acortaron el TTL del HTML a algo que coincidiera con la velocidad de actualización del contenido, quitaron
la purga programada y aplicaron purgas dirigidas en publish/update. Para el plugin de consentimiento, lo ajustaron para evitar
cambiar el HTML núcleo para usuarios anónimos y movieron la personalización a comportamiento del lado cliente.
La lección: si tu caché requiere purgas completas frecuentes para mantenerse correcto, la política de caché está mal. No necesitas un botón de purga más grande.
Necesitas menos razones para presionarlo.
Historia 3: La práctica aburrida pero correcta que salvó el día
Otro equipo tenía una política estricta de “cambiar con pruebas”. Cada cambio de caché en Cloudflare requería un pequeño script de prueba ejecutado desde
un bastión: obtener una página pública, obtener wp-admin, obtener wp-login, obtener una URL de preview, obtener la página principal con una cookie simulada
de usuario logueado y registrar los encabezados clave.
Se sentía lento, especialmente cuando los equipos de producto querían ganancias instantáneas de rendimiento. Pero el equipo tenía cicatrices. Habían visto caches
filtrar estado antes, y preferían lo aburrido sobre lo dramático.
Un viernes, se propuso una nueva optimización: cachear HTML en el borde para un conjunto de landing pages de marketing. El ingeniero corrió el
script y notó algo raro: las landing pages establecían una cookie de una herramienta de automatización de marketing en la primera vista, y el HTML
cambiaba sutilmente para incluir un estado personalizado en un píxel de tracking.
Porque la cookie estaba presente para muchos usuarios, el caché habría servido la variante “cookie-presente” a usuarios sin cookie y viceversa, y el equipo
de marketing habría acusado a las analíticas de “ser inestables.” En su lugar, implementaron cacheo en el borde solo para activos y mantuvieron el HTML conservador
hasta refactorizar los scripts de la landing page.
No explotó nada. Nadie fue notificado. El fin de semana se mantuvo intacto. Esto es lo que a menudo significa éxito en operaciones: silencio.
Listas de verificación / plan paso a paso
Paso a paso: configuración segura de caché Cloudflare para WordPress
-
Empieza con activos estáticos solamente.
- Establece Edge TTL y Browser TTL largos para activos versionados.
- Valida
CF-Cache-Status: HITpara.css,.js, imágenes.
-
Instala reglas de bypass no negociables.
- Bypass
/wp-admin/*,/wp-login.php,/wp-admin/admin-ajax.php, parámetros de preview. - Verifica que muestren
CF-Cache-Status: DYNAMICoBYPASS.
- Bypass
-
Añade bypass por cookie para sesiones autenticadas y con estado.
- Bypass cuando la cookie coincida con
wordpress_logged_in_*,wordpress_sec_*,wp-postpass_*. - Si ecommerce: bypass para cookies WooCommerce y rutas cart/checkout.
- Bypass cuando la cookie coincida con
-
Si cacheas HTML en el borde, hazlo explícita y cuidadosamente.
- Cachea HTML público solo cuando no haya cookies de estado presentes.
- Establece un TTL sensato (empieza 5–15 minutos) y ajusta después de observar la frecuencia de actualizaciones.
-
Define una política de purga.
- Prefiere purgas dirigidas en eventos de publish/update.
- Evita purgas programadas de sitio completo a menos que te guste la estampida al origen.
-
Prueba con flujos reales.
- Inicia sesión, edita, previsualiza, publica, sube medios, actualiza menús.
- Verifica que no se cacheen endpoints admin y que no aparezca preview obsoleto.
-
Observa e itera.
- Monitorea tasa de aciertos, TTFB del origen y tasas de error.
- Cualquier plugin nuevo que establezca cookies se convierte en ítem de revisión de caché.
Lista de operaciones: antes y después de cualquier cambio de caché
- Confirmar que
/wp-admin/no esté cacheado. - Confirmar que
/wp-login.phpno esté cacheado. - Confirmar que las URLs de preview no estén cacheadas.
- Confirmar que la homepage esté cacheada para peticiones anónimas (si planeas cacheo de HTML).
- Confirmar que la homepage bypassee cuando exista cookie
wordpress_logged_in_*. - Confirmar bypass de carrito/checkout de WooCommerce (si aplica).
- Confirmar que la cadena de redirección sea correcta (HTTP→HTTPS, normalización www).
- Confirmar que no aparezca desafío WAF en medio de una acción admin.
- Registrar encabezados antes/después:
CF-Cache-Status,Cache-Control,Vary. - Tener un plan de rollback: desactivar la regla de cacheo de HTML, purgar HTML, mantener cacheo estático.
Preguntas frecuentes
1) ¿Puedo cachear wp-admin para hacerlo más rápido?
No, no de forma segura. wp-admin es autenticado, usa muchos nonces y es específico por usuario. Hazlo más rápido arreglando PHP/DB/caché de objetos y
reduciendo plugins en admin. Cachea activos estáticos globalmente; deja admin dinámico.
2) ¿“Cache Everything” siempre es malo para WordPress?
No siempre. Es peligroso cuando se usa de forma amplia sin reglas estrictas de bypass. Si lo emparejas con bypass para admin/login/preview
y bypass por cookie para sesiones con estado, puede funcionar bien para contenido público.
3) ¿Cuál es la lista mínima de cookies para bypass en WordPress?
wordpress_logged_in_*, wordpress_sec_* y wp-postpass_*. Luego añade cookies de WooCommerce o
cookies de plugins de membresía según sea necesario.
4) ¿Por qué se rompen específicamente las vistas previas?
Las URLs de preview incluyen parámetros que representan un permiso con tiempo limitado para ver contenido en borrador. Si cacheas esa respuesta,
puedes servir borradores obsoletos—o servir una preview a alguien que no debería verla. Bypassea parámetros de preview.
5) ¿Necesito bypassear /wp-json/?
Para peticiones autenticadas, sí. Para endpoints públicos, depende. Si no tienes un beneficio claro y un plan de TTL corto,
mantenlo dinámico. Cachear REST es fácil de hacer mal de forma sutil.
6) Mi sitio establece muchas cookies para usuarios anónimos. ¿Significa eso que no puedo cachear HTML?
No necesariamente. La pregunta es si el HTML varía por esas cookies. Si lo hace, mueve la personalización al cliente o varía el caché con cuidado en un conjunto pequeño y controlado.
Si no lo hace, ignóralas para las decisiones de caché.
7) ¿Por qué mi tasa de aciertos es baja aunque habilité caché?
Razones comunes: estás variando por demasiadas cosas (encabezados/cookies), el TTL es demasiado corto, los query strings crean muchas variantes,
o estás purgando con demasiada frecuencia. Mide CF-Cache-Status en las URLs principales y reduce variaciones innecesarias.
8) ¿Debo confiar en el Cache-Control del origen o en los Edge TTL de Cloudflare?
Idealmente ambos se alinean. En la práctica, prefiero reglas explícitas de Cloudflare para qué se cachea y por cuánto, y mantener encabezados del origen sensatos:
“no-store” para admin/personalizado, indicios de caché razonables para contenido público. Prueba el resultado, no lo discutas.
9) ¿Necesito purgar en cada actualización de post?
Si cacheas HTML en el borde y los editores esperan actualizaciones casi instantáneas, sí—al menos para las páginas afectadas (URL del post, homepage,
páginas de categoría). Si toleras un pequeño retraso, usa TTL más corto y purga menos. Elige una: simplicidad operativa o frescura instantánea.
10) ¿Cuál es la primera ganancia de rendimiento más segura que no tocará wp-admin?
Cachea activos estáticos en el borde con TTL largos, activa compresión y optimiza PHP/DB en el origen para admin. Esto te brinda velocidad visible sin
arriesgar flujos autenticados.
Conclusión: próximos pasos que perduran
El caché de Cloudflare no “rompe wp-admin”. La gente rompe wp-admin cacheando cosas que nunca deberían cachearse, y luego
asumiendo que el borde inferirá mágicamente el estado del usuario por vibras. La solución es mecánica: excluye admin/login/preview, bypassea
por cookies de estado y trata el cacheo de HTML como una funcionalidad controlada con pruebas.
Pasos prácticos siguientes:
- Ejecuta las comprobaciones de encabezados para homepage, wp-admin, wp-login y una URL de preview. Registra
CF-Cache-Status. - Implementa reglas de bypass por ruta para admin/login/admin-ajax y parámetros de preview. Verifica inmediatamente con curl.
- Añade bypass por cookie para cookies de autenticación de WordPress y cookies de ecommerce/sesión.
- Si cacheas HTML, empieza con un TTL corto y purgas dirigidas en publish. Nunca programes purgas completas como estilo de vida.
- Cuando wp-admin esté lento, deja de culpar al caché y mide TTFB del origen. Luego ajusta PHP-FPM y la base de datos como un adulto.