WordPress tiene su propio planificador de tareas integrado llamado WP-Cron. Se encarga de todo lo que debe ocurrir según un horario: publicar entradas a una hora concreta, comprobar actualizaciones, enviar notificaciones por correo, limpiar basura de la base de datos o ejecutar tareas en segundo plano de los plugins. Suena razonable, hasta que descubres cómo funciona realmente. A diferencia de un sistema cron de verdad que se ejecuta con un temporizador fijo, WP-Cron solo se dispara cuando alguien visita tu sitio. Sin visitas, no hay cron. Y esa decisión de diseño conlleva toda una serie de problemas.
Cómo se dispara WP-Cron al cargar una página
Cada vez que se carga una página en tu sitio WordPress, WordPress comprueba una lista de eventos programados. Si alguno está atrasado, lo dispara durante esa carga. El visitante que activó la comprobación no nota nada distinto; las tareas cron se ejecutan en segundo plano (más o menos). Pero lo importante es entender que no hay ningún proceso independiente que vaya marcando el tiempo. Todo el sistema de programación se apoya en el tráfico HTTP entrante.
Fue una elección pragmática. WordPress se diseñó para funcionar en alojamientos compartidos baratos donde no puedes instalar servicios del sistema ni acceder a crontab. El enfoque basado en tráfico aseguraba que las tareas programadas funcionaran de inmediato, en cualquier alojamiento, sin configurar el servidor.
Problemas de WP-Cron: programaciones perdidas, rendimiento y desfase
El diseño dependiente del tráfico tiene problemas evidentes que se vuelven más dolorosos a medida que tu sitio crece o, paradójicamente, cuando no crece lo suficiente:
- Los sitios con poco tráfico se saltan su programación. Si tu sitio recibe 10 visitas al día, las entradas programadas pueden publicarse con horas de retraso. Una entrada programada para las 8:00 no se publicará hasta que alguien visite el sitio después de esa hora, lo que podría ser mediodía si tu audiencia está en otra zona horaria. El procesamiento de pedidos de WooCommerce, las copias de seguridad programadas y los resúmenes por correo sufren la misma suerte.
- Los sitios con mucho tráfico desperdician recursos. En un sitio con mucha actividad, WP-Cron se dispara en casi cada carga de página. WordPress comprueba la lista de eventos, evalúa marcas de tiempo y (la mayoría de las veces) no encuentra nada que hacer. Eso es cómputo desperdiciado en cada petición. Peor aún, varios visitantes simultáneos pueden disparar la misma comprobación cron a la vez, generando condiciones de carrera donde la misma tarea se ejecuta dos veces.
- Las tareas largas ralentizan la carga de páginas. Cuando WP-Cron se dispara, las tareas se ejecutan como parte de la petición de la página. WordPress intenta lanzar una petición separada en segundo plano para el trabajo cron real, pero en algunas configuraciones de servidor esto falla silenciosamente y las tareas se ejecutan en línea. Un plugin de copia de seguridad que genera un volcado de base de datos de 500 MB puede bloquear la carga de la página de un visitante si la conexión loopback no funciona correctamente.
- El desfase de cron se acumula. Como los eventos solo se ejecutan cuando los dispara el tráfico, los tiempos son aproximados en el mejor de los casos. Una tarea programada cada hora podría ejecutarse a las 1:00, 2:17, 3:02, 4:45, según cuándo llegue la siguiente visita después de la hora programada.
Tareas de WordPress que dependen de WP-Cron
Quizá te sorprenda cuánto depende de este sistema:
- Publicar entradas y páginas programadas a su fecha y hora establecidas
- Comprobar actualizaciones del núcleo de WordPress, plugins y temas
- Procesar tareas en segundo plano de WooCommerce (cambios de estado de pedidos, ofertas programadas, gestión de stock)
- Ejecutar plugins de copia de seguridad automatizada (UpdraftPlus, BackWPup, BlogVault)
- Enviar campañas o resúmenes por correo programados
- Limpiar transients caducados, entradas en la papelera e historial de revisiones
- Procesar tareas en cola de plugins de formularios, membresía y LMS
- Renovar certificados SSL de Let's Encrypt (en alojamientos que lo gestionan a través de WordPress)
Si WP-Cron no es fiable, todo lo anterior tampoco lo será.
Cómo sustituir WP-Cron por una tarea cron real del servidor
La recomendación estándar para cualquier sitio que se tome en serio la programación es deshabilitar el disparador basado en tráfico y sustituirlo por una tarea cron real del sistema. Es un proceso de dos pasos:
Paso 1: Añade esta línea a tu wp-config.php para evitar que WordPress dispare cron en cada carga de página:
define('DISABLE_WP_CRON', true);Paso 2: Configura una tarea cron del sistema para llamar a wp-cron.php a un intervalo fijo. La mayoría de los paneles de control de alojamiento (cPanel, Plesk) tienen un gestor de tareas cron, o puedes usar crontab -e en un servidor que controles:
# Llamar a WP-Cron cada 5 minutos con wget
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
# Alternativa con curl
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
# Alternativa con WP-CLI (recomendada para llamadas locales, evita la sobrecarga HTTP)
*/5 * * * * cd /var/www/html && wp cron event run --due-now >/dev/null 2>&1El enfoque con WP-CLI es el más limpio porque no implica una petición HTTP. Ejecuta los eventos cron directamente vía PHP, lo que evita problemas con conexiones loopback, tiempos de espera HTTP y autenticación (por ejemplo, autenticación HTTP básica en sitios de staging).
WP-Cron en alojamientos WordPress gestionados
Muchos alojamientos WordPress gestionados (Kinsta, WP Engine, Cloudways, SiteGround) deshabilitan el comportamiento por defecto de WP-Cron y lo sustituyen automáticamente por un cron del lado del servidor. Si estás en un alojamiento gestionado, consulta su documentación; puede que no tengas que hacer nada. Pero comprueba que realmente funciona, porque algunos alojamientos fijan un intervalo muy largo (cada 30 minutos o incluso por horas) que puede ser demasiado infrecuente para tus necesidades.
¿Es wp-cron.php un riesgo de seguridad?
El archivo wp-cron.php es accesible públicamente por defecto. Visitarlo desde un navegador dispara la comprobación cron manualmente. Aunque esto no expone datos sensibles, puede usarse de forma abusiva: un atacante que inunde el endpoint con peticiones puede forzar la ejecución repetida de tareas cron intensivas, generando una condición de denegación de servicio.
Si ya has cambiado a un cron del sistema, no hay ninguna razón para que wp-cron.php sea accesible públicamente. Puedes bloquear el acceso externo desde la configuración de tu servidor web manteniendo a la vez la posibilidad de que el cron del sistema lo llame localmente.
Depurar tareas cron de WordPress con WP Crontrol
Si las tareas programadas no se ejecutan como esperas, el plugin WP Crontrol es muy valioso. Añade una página al administrador de WordPress que muestra todos los eventos cron registrados, su próxima hora de ejecución y su frecuencia. Puedes disparar manualmente cualquier evento, eliminar eventos atascados o añadir nuevas programaciones personalizadas. Es la primera herramienta que instalar al diagnosticar problemas de cron.
Comprueba tu configuración de WP-Cron con InspectWP
InspectWP comprueba si tu archivo wp-cron.php es accesible públicamente. Si has migrado a un cron del sistema y has deshabilitado el WP-Cron integrado, el endpoint no debería ser accesible desde fuera. El informe te ayuda a confirmar que tu configuración cron es correcta y que no estás dejando expuesto un endpoint innecesario.