Varnish Cache para PrestaShop: Cuando los módulos de Full Page Cache no son suficientes
Qué es Varnish y por qué importa para PrestaShop
Varnish Cache es un proxy inverso HTTP que se sitúa entre tu servidor web e internet, sirviendo copias cacheadas de las páginas sin tocar jamás PHP ni MySQL. Cuando un visitante solicita una página que Varnish tiene en caché, la respuesta llega directamente desde la memoria en microsegundos. PHP nunca se ejecuta. MySQL nunca recibe una consulta. El servidor web apenas nota que la solicitud ha ocurrido.
Esto es fundamentalmente diferente de cómo funcionan los módulos de full page cache (FPC) basados en PHP en PrestaShop. Un módulo FPC sigue ejecutándose dentro de PHP. La solicitud llega a Apache o Nginx, PHP se inicia, PrestaShop se inicializa (cargando la configuración, estableciendo conexiones a la base de datos, analizando las rutas), y luego el módulo FPC intercepta la solicitud antes de que se ejecute la lógica completa del controlador, sirviendo un archivo HTML cacheado. Aunque esto es significativamente más rápido que renderizar la página desde cero, aún implica iniciar PHP y cargar el framework de PrestaShop. Esa sobrecarga, típicamente de 50-200 milisegundos incluso para un acierto de caché, se acumula bajo carga.
Varnish elimina completamente esa sobrecarga. Un acierto de caché de Varnish se sirve en 1-5 milisegundos. Con tráfico elevado, la diferencia es dramática. Una tienda PrestaShop que lucha por manejar 100 usuarios simultáneos con un módulo FPC puede servir miles de usuarios simultáneos con Varnish, porque la gran mayoría de las solicitudes nunca llegan al backend PHP.
Cuándo los módulos PHP Full Page Cache son suficientes
Antes de invertir en Varnish, vale la pena entender cuándo un módulo FPC basado en PHP es suficientemente bueno. Para muchas tiendas PrestaShop, lo es.
Si tu tienda recibe menos de 50.000 páginas vistas diarias, un módulo FPC bien configurado manejará la carga sin problemas. La complejidad adicional de Varnish no está justificada cuando tu servidor tiene capacidad de reserva. Si los tiempos de respuesta del servidor con FPC son consistentemente inferiores a 200 milisegundos, tus visitantes ya están obteniendo cargas de página rápidas. El cuello de botella en ese punto es probablemente el renderizado frontend (CSS, JavaScript, imágenes) en lugar del tiempo de respuesta del servidor.
Los módulos FPC manejan algunos escenarios específicos de PrestaShop con más elegancia que Varnish porque se ejecutan dentro de la aplicación. Pueden verificar si un usuario está conectado, si el carrito tiene artículos y si cierto contenido dinámico necesita personalización — todo dentro del mismo proceso PHP. Con Varnish, estas comprobaciones deben manejarse mediante la inspección de cookies y reglas de variación de caché, lo que añade complejidad a la configuración.
Considera Varnish cuando tu tienda maneja regularmente picos de tráfico (ventas flash, campañas de marketing, picos estacionales) que sobrecargan tu capacidad PHP, cuando necesitas tiempos de respuesta inferiores a 10 ms por razones de SEO o experiencia de usuario, cuando tu presupuesto de hosting es limitado y necesitas servir más tráfico con el mismo hardware, o cuando tu tienda sirve una alta proporción de navegación anónima (páginas de categoría, páginas de producto) en relación con la actividad del carrito y el checkout.
Cómo funciona Varnish: El flujo de solicitudes
Comprender el flujo de solicitudes a través de Varnish es esencial para configurarlo correctamente con PrestaShop.
Llegada de la solicitud
Cuando un visitante solicita una página, la solicitud llega primero a Varnish (Varnish escucha en el puerto 80 o 443 si la terminación SSL es manejada por un proxy frontend). Varnish examina la solicitud: la URL, el método HTTP, las cookies y los encabezados.
Búsqueda en caché
Varnish comprueba su caché en busca de una respuesta almacenada que coincida con esta solicitud. La clave de caché se basa típicamente en la URL y encabezados seleccionados. Si existe una respuesta coincidente y no ha expirado, Varnish la sirve directamente. Esto es un acierto de caché (cache hit). La respuesta se envía al visitante y el servidor backend nunca es contactado.
Fallo de caché
Si no existe una respuesta cacheada coincidente, Varnish reenvía la solicitud al servidor backend (Apache o Nginx ejecutando PrestaShop). PrestaShop procesa la solicitud normalmente, genera la respuesta HTML y la envía de vuelta a Varnish. Varnish almacena la respuesta en su caché (si la respuesta es cacheable) y la reenvía al visitante. Las solicitudes posteriores de la misma página se servirán desde la caché.
Invalidación de caché
Cuando los datos del producto cambian, los precios se actualizan o el contenido se modifica, la versión en caché se vuelve obsoleta. Varnish necesita ser informado de descartar la versión antigua cacheada para que obtenga una nueva del backend. Esto es la invalidación de caché, y es la parte más difícil de cualquier sistema de caché para implementar correctamente.
Configuración VCL para PrestaShop
Varnish Configuration Language (VCL) es un lenguaje específico de dominio que controla cómo Varnish maneja las solicitudes. Una configuración VCL adecuada para PrestaShop debe manejar varios comportamientos específicos de PrestaShop.
Definición del backend
La definición del backend le indica a Varnish dónde reenviar los fallos de caché. Para una configuración típica de PrestaShop donde Apache o Nginx se ejecuta en el mismo servidor en el puerto 8080:
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 5s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 10s;
}
Los timeouts son importantes. Las páginas de PrestaShop pueden tardar varios segundos en generarse con caché fría, especialmente las páginas de categoría con muchos productos. Configurar first_byte_timeout demasiado bajo hace que Varnish devuelva un error 503 antes de que PrestaShop termine de generar la página.
Manejo de cookies y sesiones
Las cookies son el mayor desafío al hacer caché de PrestaShop con Varnish. PrestaShop establece varias cookies por defecto, y Varnish trata cualquier solicitud con cookies como no cacheable a menos que se le indique lo contrario. Si no manejas las cookies en tu VCL, Varnish no cacheará prácticamente nada.
PrestaShop establece estas cookies en la mayoría de las solicitudes: la cookie de sesión (típicamente llamada PrestaShop-xxxx), las cookies relacionadas con el carrito, las cookies de Google Analytics (_ga, _gid, _gat) y varias cookies de seguimiento de herramientas de marketing. De estas, solo la cookie de sesión de PrestaShop importa para el comportamiento de la caché. Las cookies de analytics y seguimiento deben eliminarse de la solicitud antes de la búsqueda en caché para que no impidan el caching.
En tu subrutina VCL vcl_recv, elimina las cookies no esenciales:
sub vcl_recv {
# Eliminar cookies de Google Analytics y otros rastreadores
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_ga|_gid|_gat|__utm[a-z]+|_fbp|_gcl_[a-z]+)=[^;]*", "");
# Eliminar encabezado de cookie vacío
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
}
Decidir qué cachear
No todas las páginas de PrestaShop deben cachearse. El VCL debe distinguir entre solicitudes cacheables y no cacheables.
Cachear siempre: Páginas de producto para visitantes anónimos, páginas de listado de categorías, páginas CMS (acerca de, términos, contacto), la página de inicio, páginas de fabricantes y proveedores, páginas del mapa del sitio.
Nunca cachear: La página del carrito, las páginas de checkout (todos los pasos), el área de cuenta del cliente (pedidos, direcciones, información personal), las páginas de login y registro, cualquier página para un cliente conectado, solicitudes POST, solicitudes AJAX que modifican el estado (añadir al carrito, actualizar cantidad).
La lógica VCL para esto típicamente comprueba la ruta de la URL y la presencia de cookies de sesión:
sub vcl_recv {
# No cachear solicitudes POST
if (req.method == "POST") {
return (pass);
}
# No cachear área de administración
if (req.url ~ "^/admin") {
return (pass);
}
# No cachear checkout y carrito
if (req.url ~ "(cart|order|login|my-account|module/)" ) {
return (pass);
}
# No cachear si el cliente tiene artículos en el carrito
if (req.http.Cookie ~ "PrestaShop-") {
return (pass);
}
return (hash);
}
Establecer la duración de la caché
En la subrutina vcl_backend_response, controlas cuánto tiempo Varnish cachea cada respuesta. PrestaShop envía encabezados Cache-Control que típicamente dicen no-cache o private porque asume que cada respuesta puede contener contenido personalizado. Necesitas sobrescribirlos para las páginas que sabes que son seguras para cachear:
sub vcl_backend_response {
# Cachear páginas de producto y categoría por 1 hora
if (bereq.url ~ "^/([0-9]+-|[a-z]+-[0-9]+)") {
set beresp.ttl = 1h;
unset beresp.http.Set-Cookie;
}
# Cachear activos estáticos por 1 día
if (bereq.url ~ "\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf)$") {
set beresp.ttl = 1d;
unset beresp.http.Set-Cookie;
}
}
Eliminar Set-Cookie de las respuestas cacheadas es crítico. Si una respuesta cacheada incluye un encabezado Set-Cookie, Varnish no la cacheará por defecto, e incluso si se le obliga a cachear, establecería la misma cookie de sesión para cada visitante, causando secuestro de sesión (session hijacking).
Invalidación de caché con solicitudes PURGE
Cuando el precio de un producto cambia, se añade un nuevo producto o se actualiza el contenido, la versión cacheada debe invalidarse. Varnish soporta solicitudes PURGE: un método HTTP especial que le indica a Varnish que elimine una URL específica de su caché.
Configurar el soporte PURGE
Añade el manejo de PURGE a tu VCL:
acl purge {
"127.0.0.1";
"localhost";
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
}
return (purge);
}
}
La ACL restringe las solicitudes PURGE a localhost, impidiendo que usuarios externos vacíen tu caché.
Disparar purgas desde PrestaShop
PrestaShop no envía nativamente solicitudes PURGE. Necesitas un módulo o hook personalizado que detecte cuándo cambia el contenido cacheable y envíe una solicitud PURGE a Varnish. El módulo se engancha a eventos de PrestaShop como actionProductUpdate, actionCategoryUpdate y actionCMSPageUpdate. Cuando estos eventos se disparan, el módulo envía una solicitud HTTP PURGE a la URL correspondiente en el servidor Varnish.
Para una actualización de producto, el módulo purgaría la URL del producto, las URLs de las categorías a las que pertenece el producto (porque las páginas de listado de categorías muestran precios y disponibilidad de productos) y potencialmente la página de inicio si muestra productos destacados. Esta cascada de purgas es necesaria para evitar que datos obsoletos aparezcan en cualquier parte del sitio.
Invalidación basada en BAN
Para escenarios donde muchas URLs necesitan purgarse a la vez (una actualización de precios a nivel de sitio, un cambio de diseño, un nuevo banner promocional), las solicitudes PURGE individuales son impracticables. Varnish soporta bans, que son reglas de invalidación basadas en patrones. Un ban le indica a Varnish que descarte cualquier objeto cacheado que coincida con un patrón:
sub vcl_recv {
if (req.method == "BAN") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
}
ban("req.url ~ " + req.http.X-Ban-Pattern);
return (synth(200, "Banned."));
}
}
Enviar una solicitud BAN con el encabezado X-Ban-Pattern: /category/ invalidaría todas las páginas de categoría cacheadas en una sola operación.
Edge Side Includes (ESI) para bloques dinámicos
Muchas páginas de PrestaShop contienen una mezcla de contenido estático y dinámico. El listado de productos en una página de categoría es el mismo para cada visitante, pero el encabezado que muestra el contador del carrito es personalizado. Sin ESI, no puedes cachear la página en absoluto porque el encabezado dinámico hace que toda la respuesta sea específica del visitante.
Los Edge Side Includes resuelven esto permitiéndote marcar secciones de la página como fragmentos recuperados por separado. Varnish ensambla la página final a partir de fragmentos cacheados y no cacheados.
Cómo funciona ESI
En tu plantilla Smarty, en lugar de renderizar el widget del carrito directamente, incluyes una etiqueta ESI:
<esi:include src="/module/cartwidget/ajax" />
Cuando Varnish procesa la página cacheada, encuentra la etiqueta ESI y realiza una solicitud separada al backend para ese fragmento. El cuerpo principal de la página se sirve desde la caché, mientras que el widget del carrito se obtiene fresco de PrestaShop. La respuesta ensamblada incluye tanto el cuerpo cacheado como el widget del carrito actualizado.
Habilita el procesamiento ESI en tu VCL:
sub vcl_backend_response {
set beresp.do_esi = true;
}
Consideraciones ESI para PrestaShop
Implementar ESI requiere modificar tus plantillas de PrestaShop para separar el contenido dinámico en fragmentos compatibles con ESI. Cada fragmento necesita su propio endpoint URL que devuelva solo el HTML para ese bloque. Los fragmentos que típicamente son dinámicos y necesitan tratamiento ESI incluyen el widget resumen del carrito (conteo de artículos, total), el saludo al cliente ("Hola, Juan"), cualquier recomendación personalizada de productos, el enlace de login/logout y los productos vistos recientemente.
El esfuerzo requerido para implementar ESI correctamente es significativo. Cada fragmento dinámico necesita un controlador dedicado, las plantillas requieren reestructuración y las reglas de caching para cada fragmento necesitan ajuste individual. Esta es una de las razones por las que Varnish se considera una optimización avanzada — funciona mejor cuando la aplicación está diseñada teniéndolo en cuenta.
Comprobaciones de salud del backend
Varnish puede monitorear la salud de tu servidor backend y actuar cuando se vuelve no disponible. Esto se configura en la definición del backend:
backend default {
.host = "127.0.0.1";
.port = "8080";
.probe = {
.url = "/ping.php";
.timeout = 2s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
Varnish envía una solicitud a /ping.php cada 5 segundos. Si 3 de las últimas 5 comprobaciones fallan, Varnish marca el backend como enfermo. Mientras el backend está enfermo, Varnish puede servir contenido cacheado obsoleto (modo grace) en lugar de devolver errores a los visitantes. Esto significa que tu tienda permanece parcialmente disponible incluso cuando el backend PHP se cae o se reinicia.
La configuración del modo grace determina cuánto tiempo Varnish servirá contenido obsoleto:
sub vcl_backend_response {
set beresp.grace = 6h;
}
Con un grace de 6 horas, si tu backend cae, los visitantes verán páginas cacheadas (aunque tengan hasta 6 horas de antigüedad) en lugar de páginas de error. Los precios de los productos podrían estar ligeramente desactualizados, pero la tienda sigue funcional mientras solucionas el problema del backend.
Benchmarks de rendimiento
La diferencia de rendimiento entre sin caché, PHP FPC y Varnish es sustancial y medible.
Sin caché (PrestaShop puro): Una página de producto típica de PrestaShop tarda 200-800 milisegundos en generarse, dependiendo del hardware del servidor, el número de módulos cargados y la cantidad de consultas a la base de datos. Bajo carga, los tiempos de respuesta aumentan porque los workers PHP están saturados. Un solo servidor puede manejar 20-50 usuarios simultáneos antes de que los tiempos de respuesta se vuelvan inaceptables.
Módulo PHP FPC: Los aciertos de caché se sirven en 30-100 milisegundos porque PHP aún se inicia y el framework se inicializa parcialmente. Bajo carga, el rendimiento es mucho mejor porque las respuestas cacheadas requieren un tiempo de procesamiento PHP mínimo. Un solo servidor puede manejar 200-500 usuarios simultáneos dependiendo de la configuración. Los fallos de caché aún toman el tiempo completo de renderizado.
Varnish: Los aciertos de caché se sirven en 1-5 milisegundos. Bajo carga, Varnish mismo puede manejar miles de conexiones simultáneas porque está escrito en C y diseñado específicamente para este tipo de carga de trabajo. El servidor backend solo maneja los fallos de caché, que son una pequeña fracción del tráfico total en un sistema correctamente configurado. El mismo hardware que lucha con 50 usuarios simultáneos sin caché puede manejar 5.000 o más con Varnish.
Estos números ilustran por qué Varnish vale la complejidad de configuración para tiendas de alto tráfico. La mejora de rendimiento no es incremental — es de un orden de magnitud.
Requisitos de hosting
Varnish tiene requisitos de hosting específicos que no todos los entornos de hosting PrestaShop pueden satisfacer.
Acceso al servidor
Necesitas acceso root para instalar y configurar Varnish. Los planes de hosting compartido no soportan Varnish porque requiere su propio proceso escuchando en un puerto e interceptando todo el tráfico HTTP. Necesitas un VPS, servidor dedicado o instancia en la nube donde controles la pila completa del servidor.
Memoria
Varnish almacena su caché en RAM. La cantidad de RAM que necesitas depende del número de páginas únicas en tu catálogo y el tamaño de cada respuesta cacheada. Una fórmula aproximada: el número de páginas cacheables multiplicado por el tamaño promedio de página te da el tamaño mínimo de caché. Una tienda con 5.000 productos, 200 categorías y un tamaño promedio de página de 50KB necesita aproximadamente 260MB de caché RAM. Añade la sobrecarga para Varnish mismo y deberías asignar al menos 512MB. Para catálogos más grandes, 1-2GB es lo habitual.
Configuración de puertos
En una configuración estándar, Varnish escucha en el puerto 80 (el puerto HTTP por defecto) y reenvía los fallos de caché al servidor web en un puerto diferente (comúnmente 8080). Esto significa que necesitas reconfigurar Apache o Nginx para escuchar en el puerto 8080 en lugar del 80. Si usas HTTPS (y deberías), típicamente colocas Nginx delante de Varnish para manejar la terminación SSL: Nginx en el puerto 443 termina SSL y reenvía a Varnish en el puerto 80, que reenvía los fallos de caché a Apache o PHP-FPM en el puerto 8080.
Ejemplo de configuración Docker
Ejecutar Varnish en Docker junto a un contenedor PrestaShop es una forma limpia de añadir Varnish a una configuración existente sin modificar el sistema host.
Configuración Docker Compose
Una configuración básica de Docker Compose con Varnish, Nginx para SSL y PrestaShop:
services:
varnish:
image: varnish:7.4
ports:
- "80:80"
volumes:
- ./varnish/default.vcl:/etc/varnish/default.vcl:ro
environment:
- VARNISH_SIZE=512m
depends_on:
- prestashop
prestashop:
image: prestashop/prestashop:8
expose:
- "80"
environment:
- DB_SERVER=db
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secretpassword
- MYSQL_DATABASE=prestashop
En esta configuración, Varnish es el punto de entrada en el puerto 80. El contenedor PrestaShop no expone su puerto al host, solo a la red Docker. El host del backend VCL sería prestashop (el nombre del servicio Docker) en el puerto 80.
VCL para Docker
La definición del backend VCL para Docker usa el nombre del servicio en lugar de localhost:
backend default {
.host = "prestashop";
.port = "80";
}
El DNS interno de Docker resuelve el nombre del servicio a la IP del contenedor. El resto de la configuración VCL permanece igual que en una configuración sin Docker.
Almacenamiento de caché en Docker
Por defecto, la imagen Docker de Varnish usa almacenamiento en memoria (malloc), que es ideal para el rendimiento. La variable de entorno VARNISH_SIZE controla cuánta memoria Varnish asigna para su caché. Establece este valor en uno que quepa dentro de los límites de memoria de tu contenedor dejando espacio para el propio proceso Varnish.
Para una caché persistente que sobreviva a los reinicios del contenedor, puedes usar almacenamiento basado en archivos montando un volumen, pero esto rara vez es necesario. La caché se calienta rápidamente (en minutos de recibir tráfico) y el almacenamiento basado en archivos es más lento que el almacenamiento en memoria.
Monitorización del rendimiento de Varnish
Varnish proporciona herramientas integradas para monitorizar el rendimiento de la caché.
El comando varnishstat muestra estadísticas en tiempo real incluyendo la tasa de aciertos de caché, conexiones al backend y uso de memoria. La métrica más importante es la tasa de aciertos, que debería ser del 85% o superior para una configuración bien ajustada. Si tu tasa de aciertos está por debajo del 70%, revisa tus reglas VCL porque demasiadas solicitudes están pasando al backend.
El comando varnishlog muestra logs detallados por solicitud, que son invaluables para depurar por qué solicitudes específicas no se están cacheando. Puedes filtrar por patrón de URL, código de respuesta o estado de acierto/fallo de caché.
El comando varnishtop muestra una lista clasificada de las entradas de log más frecuentes, ayudándote a identificar patrones en los fallos de caché o errores.
Errores comunes
Olvidar eliminar cookies
La mala configuración de Varnish más común con PrestaShop es no eliminar las cookies de analytics y seguimiento. Estas cookies están presentes en prácticamente cada solicitud y hacen que cada solicitud sea única desde la perspectiva de Varnish, resultando en una tasa de aciertos del 0%. Elimina siempre las cookies que no necesitas para la variación de caché.
Cachear contenido personalizado
Si tu VCL es demasiado agresivo, cacheará páginas que contienen contenido personalizado (saludo del usuario conectado, contenido del carrito) y las servirá a otros visitantes. Esto causa serios problemas de usabilidad y potenciales problemas de privacidad. Pasa siempre las solicitudes que contienen cookies de sesión al backend.
No invalidar al cambiar contenido
Sin un mecanismo de purga adecuado, los cambios de contenido en el back office no serán visibles hasta que las páginas cacheadas expiren naturalmente. Para una tienda con cambios activos de inventario, esto significa que los visitantes podrían ver productos agotados, precios incorrectos o descripciones desactualizadas. Implementa soporte PURGE o BAN e intégralo con los hooks de actualización de PrestaShop.
Ignorar HTTPS
Varnish no maneja SSL de forma nativa. Debes colocar un proxy de terminación SSL (Nginx, HAProxy o un balanceador de carga en la nube) delante de Varnish. No planificar esto en tu arquitectura conduce a problemas de contenido mixto (mixed content), bucles de redirección o la imposibilidad de servir tráfico HTTPS en absoluto.
¿Es Varnish adecuado para tu tienda?
Varnish es una herramienta poderosa, pero no es la elección correcta para cada tienda PrestaShop. Añade complejidad operativa: otro servicio que monitorizar, otro lenguaje de configuración que aprender, otra capa en tu proceso de depuración. Los beneficios son claros y medibles para las tiendas que los necesitan, pero vienen con un coste en tiempo de configuración, mantenimiento y dificultad de resolución de problemas.
Si tu tienda sirve menos de 50.000 páginas vistas al día y tu servidor maneja la carga cómodamente con un módulo FPC, Varnish es complejidad innecesaria. Si tu tienda enfrenta regularmente picos de tráfico que sobrecargan tu servidor, sirve un alto volumen de tráfico de navegación anónima o necesita los tiempos de respuesta más rápidos posibles para SEO o experiencia de usuario, Varnish proporciona un nivel de rendimiento que ninguna solución de caching basada en PHP puede igualar.
Comienza con una optimización adecuada de PrestaShop (optimización de consultas, auditoría de módulos, PHP OPcache, optimización de imágenes) y un módulo FPC. Si esas optimizaciones no son suficientes, Varnish es el siguiente paso en la escalera de escalado del rendimiento.
¿Le resultó útil esta respuesta?
¿Aún tiene preguntas?
Can't find what you're looking for? Send us your question and we'll get back to you quickly.