WP-Cron (wp-cron.php): desactivarlo y configurar un cron del sistema | Optimización del rendimiento de WordPress

En WordPress, las tareas Cron son una función que ejecuta automáticamente tareas programadas para una hora o fecha concretas. Se ejecutan a través del archivo wp-cron.php, y WordPress llama a este archivo cada vez que se carga una página para procesar las tareas programadas. Este método es sencillo, pero en sitios con mucho tráfico puede reducir el rendimiento.

Ⅰ. Cómo se ejecuta WP-Cron y sus problemas de rendimiento

En lugar del sistema Cron tradicional de los servidores Linux, WordPress ofrece su propia función Cron, WP-Cron. WP-Cron funciona a través del archivo wp-cron.php: ⓐ cada vez que un usuario visita el sitio, comprueba si hay tareas programadas y las ejecuta, y ⓑ plugins como Rank Math y WP Rocket ejecutan sus propias tareas periódicas programadas.

En cambio, en sitios con mucho tráfico wp-cron.php puede llamarse con demasiada frecuencia y sobrecargar el servidor. Sobre todo, cuando muchos usuarios se conectan a la vez se ejecutan tareas cron duplicadas, lo que puede provocar más uso de CPU, respuestas más lentas, carga de páginas más lenta y problemas similares.

Estos límites estructurales de WP-Cron pueden reducir el rendimiento de WordPress y, sobre todo en sitios que exigen alto rendimiento, tiendas online y portales de noticias pueden provocar cuellos de botella graves.

🔄 Cómo funciona y se estructura WP-Cron

WP-Cron
WP-Cron(wp-cron.php)
ⓐ Comprueba las tareas programadas en cada visita
ⓑ Tareas periódicas de los plugins(Rank Math, WP Rocket y otros)
Problemas de rendimiento de WP-Cron
Dependencia del tráfico
Sobrecarga del servidor por exceso de llamadas
Ejecuciones duplicadas y cuellos de botella
Cómo se ejecuta WP-Cron
Planificador virtual basado en el tráfico
Flujo de ejecución de las tareas programadas
Se ejecuta por visitas, no por horario

Ⅱ. Optimización del rendimiento de WordPress

  • ↳ Optimizar con los ajustes de WP-Cron

Hay muchas formas de optimizar el rendimiento de WordPress. Tras optimizar la caché, el frontend y la base de datos, aún puedes mejorar con los ajustes de WP-Cron.

WordPress
Optimización del rendimiento
Caché del navegador
Caché de página
Plugins de caché(WP Rocket, W3 Total Cache y otros)
Optimización del frontend
Plugins relacionados(Autoptimize, ShortPixel, etc.)
Limpieza de la base de datos
Eliminar revisiones/spam/tablas temporales
Plugins de optimización de la BD(WP-Optimize y otros)
Ajustes de WP-Cron
WP-Cron(wp-cron.php)
ⓐ Comprueba las tareas programadas en cada visita
ⓑ Tareas periódicas de los plugins(Rank Math, WP Rocket, etc.)
Problemas de rendimiento de WP-Cron
Dependencia del tráfico
Sobrecarga del servidor por exceso de llamadas
Ejecuciones duplicadas y cuellos de botella
Cómo se ejecuta WP-Cron
Planificador virtual basado en el tráfico
Flujo de ejecución de las tareas programadas
Se ejecuta por visitas, no por horario

Los eventos programados se comprueban cada vez que se carga una página de WordPress y, por las tareas periódicas de los plugins, conviene aprovechar mejor un WP-Cron poco eficiente.

1️⃣ Probar WP-Cron

Al revisar las tareas cron con WP-CLI se ve cómo se ejecuta el Cron activo. Se comprueba que plugins como Rank Math y WP Rocket ejecutan tareas programadas a diario o cada pocos minutos.

WP CLI- comprobar los eventos cron programados con el comando wp-cron event list_

2️⃣ Cómo configurar WP-Cron

WP-Cron es un planificador virtual que gestiona las tareas programadas de WordPress; wp-cron.php se ejecuta cuando los usuarios visitan el sitio. Pero la ejecución basada en el tráfico es inestable y el exceso de llamadas puede sobrecargar el servidor, por lo que lo habitual es complementarlo con un cron del sistema.
Si hace falta, se recomienda definir DISABLE_WP_CRON en wp-config.php para desactivar WP-Cron y ejecutarlo periódicamente con un cron de Linux.

Categoría

Desactivar WP-Cron + ejecutar solo el cron del sistema

Ajustes

Desactivar WP-Cron y ejecutar wp-cron.php desde el cron del sistema

Ventajas

Sin ejecuciones duplicadas, ejecución precisa por horario y poca carga del servidor

Desventajas

Algunas funciones de plugins pueden dejar de funcionar y un error de configuración puede hacer que se pierdan tareas

Recomendado · Situación

Adecuado para sitios con mucho tráfico y muchas tareas programadas

Sin embargo, el método ① tiene un inconveniente: desactiva la función de precarga (PreLoad) de plugins de caché como WP Rocket, que cada minuto genera la caché antes de que lleguen los visitantes.

⚙️ Editar el archivo wp-config.php

Puedes configurarlo desactivando WP_CRON.

# Desactivar WP_CRON
define( 'DISABLE_WP_CRON', true );

Mientras WP-Cron se ejecuta, WP_CRON_LOCK_TIMEOUT actúa como un [bloqueo por tiempo] que impide otros intentos de ejecución.

# 5 minutos = 300, cada 60 minutos = 3600
define('WP_CRON_LOCK_TIMEOUT', 300);

Por estas razones, en lugar de solo desactivar WP-Cron en el archivo wp-config.php, recomiendo desactivarlo y después añadir System Cron como tarea; el servidor que gestiono actualmente también está configurado así.

⚙️ Activar un cron del sistema en un servidor Linux [básico]

Puedes activarlo por dominio.

# Ejecutar cada 5 minutos
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Ejecutar cada 30 minutos
*/30 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Ejecutar cada hora
0 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
# Ejecutar una vez al día
0 3 * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Las cuatro líneas de arriba son ejemplos por intervalo para añadir al crontab: a cada hora fijada, curl llama a la URL [wp-cron.php], así que las tareas programadas se ejecutan aunque no haya visitas.

# Si el servidor es local
*/5 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1

# Ejecutar cada 30 minutos
*/30 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1

# Ejecutar cada hora
0 * * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1

# Ejecutar una vez al día
0 3 * * * php /path/to/wordpress/wp-cron.php > /dev/null 2>&1

Si tienes WP-CLI instalado, puedes configurar una sola línea con el intervalo que quieras. ▼

# Ejecutar cada 5 minutos
*/5 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet

# Ejecutar cada 30 minutos
*/30 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet

# Ejecutar cada hora
0 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet

# Ejecutar una vez al día
0 3 * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet

Con esta configuración, WP-CLI ejecuta dentro del servidor solo las tareas programadas que ya tocan, con la opción [--due-now], y [flock -n] omite una nueva ejecución si la anterior no ha terminado.

⚙️ WP-CLI y cron del sistema cada minuto, y evitar tareas cron duplicadas

Por defecto, WP_CRON simplemente ignora (omite) las tareas cuando hay mucha carga y las vuelve a ejecutar después. Desactiva el WP-Cron predeterminado y configura las tareas programadas para mantener un bloqueo de 5 minutos, de modo que el cron del sistema y WP-Cron no se ejecuten a la vez.

define('DISABLE_WP_CRON', true);         // desactiva la ejecución automática de WP-Cron
define('WP_CRON_LOCK_TIMEOUT', 300);     // sin espera → se omite; mantiene un bloqueo de 5 minutos mientras se ejecuta una tarea programada

/* That's all, stop editing! Happy publishing. */

Añade la opción flock -n al cron del sistema para que, en ese lado, la ejecución termine de inmediato.

# Configuración de wp cron: flock -n → sin espera → salida inmediata
*/1 * * * * cd /sites/example.com/files/ && flock -n ~/.wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet

El resultado de combinar estos ajustes es:

  • La ejecución automática interna de WP está desactivada → las tareas programadas se ejecutan sin depender de las visitas
  • El cron del sistema intenta ejecutarse cada minuto → si hay tareas programadas, se ejecutan
  • Con el bloqueo activo, no se vuelve a ejecutar durante 5 minutos → evita ejecuciones duplicadas (en la práctica, con flock -n, WP_CRON_LOCK_TIMEOUT no es realmente necesario.)

Con la prevención de duplicados, el flujo real es:

  1. 08:00 → el cron del sistema llama a wp-cron.php
    • Se ejecuta la tarea programada A → se fija un bloqueo de 5 minutos
  2. 08:01 → el cron del sistema vuelve a llamar
    • La tarea A está bloqueada → no se ejecuta
  3. 08:02–08:04 → igual
    • 08:05 → se libera el bloqueo → si hay otra tarea programada, se ejecuta

En lugar de que WordPress ejecute las tareas automáticamente, el sistema se encarga de ejecutarlas. Y WP_CRON_LOCK_TIMEOUT funciona como una salvaguarda adicional contra las ejecuciones duplicadas.

Categoría

WP_CRON_LOCK_TIMEOUT

flock -n

Tipo de bloqueo

Dentro de WordPress

Nivel de sistema

Ubicación del bloqueo

En la BD: doing_cron en wp_options

En un archivo del sistema: ~/.wp_cron.lock

¿Espera?

❌ No espera → omite

❌ No espera → termina de inmediato

Evita duplicados

✅ Evita ejecuciones duplicadas

✅ Evita ejecuciones duplicadas

Al terminar, puedes comprobar con un comando de WP-CLI que el cron sigue funcionando como antes.

wp cron event list
+-------------------------------------------+---------------------+-----------------------+---------------+
| hook                                      | next_run_gmt        | next_run_relative     | recurrence    |
+-------------------------------------------+---------------------+-----------------------+---------------+
| rocket_saas_pending_jobs                  | 2026-10-17 12:00:57 | now                   | 1 minute      |
| action_scheduler_run_queue                | 2026-10-17 12:00:57 | now                   | 1 minute      |
| action_scheduler_run_queue_rucss          | 2026-10-17 12:00:58 | now                   | 1 minute      |
| rocket_saas_on_submit_jobs                | 2026-10-17 12:00:58 | now                   | 1 minute      |
| rocket_preload_process_pending            | 2026-10-17 12:00:59 | now                   | 1 minute      |
| rocket_purge_time_event                   | 2026-10-17 12:16:59 | 15 minutes 8 seconds  | 1 hour        |
| wp_privacy_delete_old_export_files        | 2026-10-17 12:28:46 | 26 minutes 55 seconds | 1 hour        |
| wp_update_user_counts                     | 2026-10-17 20:15:52 | 8 hours 14 minutes    | 12 hours      |
| rocket_preload_revert_old_failed_rows     | 2026-10-17 20:17:59 | 8 hours 16 minutes    | 12 hours      |
| wp_version_check                          | 2026-10-17 20:28:34 | 8 hours 26 minutes    | 12 hours      |
| wp_update_plugins                         | 2026-10-17 20:58:34 | 8 hours 56 minutes    | 12 hours      |
| wp_update_themes                          | 2026-10-17 21:28:34 | 9 hours 26 minutes    | 12 hours      |
| recovery_mode_clean_expired_keys          | 2026-10-18 07:28:46 | 19 hours 26 minutes   | 1 day         |
| wp_privacy_personal_data_cleanup_requests | 2026-10-18 07:28:46 | 19 hours 26 minutes   | 1 day         |
| wp_scheduled_delete                       | 2026-10-18 08:15:52 | 20 hours 14 minutes   | 1 day         |
| delete_expired_transients                 | 2026-10-18 08:15:52 | 20 hours 14 minutes   | 1 day         |
| wp_scheduled_auto_draft_delete            | 2026-10-18 08:15:54 | 20 hours 14 minutes   | 1 day         |
| wp_delete_temp_updater_backups            | 2026-10-18 08:16:17 | 20 hours 14 minutes   | 1 week        |
| rocket_update_dynamic_lists               | 2026-10-18 08:16:57 | 20 hours 15 minutes   | 1 week        |
| rocket_saas_clean_rows_time_event         | 2026-10-18 08:16:57 | 20 hours 15 minutes   | 1 week        |
| rocket_performance_hints_cleanup          | 2026-10-18 08:16:58 | 20 hours 15 minutes   | 1 day         |
| rocket_preload_clean_rows_time_event      | 2026-10-18 08:26:57 | 20 hours 25 minutes   | 1 week        |
| rocket_database_optimization_time_event   | 2026-10-18 09:34:25 | 21 hours 32 minutes   | 1 day         |
| wp_site_health_scheduled_check            | 2026-10-19 07:28:46 | 1 day 19 hours        | 1 week        |
| rocket_remove_saas_failed_jobs            | 2026-10-19 08:16:58 | 1 day 20 hours        | 3 days        |
+-------------------------------------------+---------------------+-----------------------+---------------+

La salida muestra los nombres de los hooks registrados, la próxima hora de ejecución y la recurrencia; las tareas cuya columna [next_run_relative] dice [now] se procesan en la siguiente ejecución del cron.

Ⅲ. Cuando las tareas programadas de WP-Cron no se ejecutan

Es fácil pensar que una tarea se ejecuta sola al llegar su hora programada, pero WP-Cron comprueba qué hay que hacer cuando llega una petición de página, no a una hora fija. Una tarea programada para las 2 de la tarde se ejecuta en la primera petición de las 5 si no llega ninguna antes.

Cuando las ejecuciones se retrasan, las entradas programadas aparecen como [Programación perdida](Missed schedule) en la lista de entradas. En [Mejoras recomendadas] de la pestaña Estado de [Herramientas › Salud del sitio] aparece [Ha fallado un evento programado]. Las tareas que registran los plugins, como la precarga de la caché, también esperan por la misma razón.

Las tareas programadas se ejecutan en [wp-cron.php] tras pasar por una petición de página, la comprobación de tareas pendientes y una petición de loopback; si se corta cualquiera de estos pasos, no se ejecutan aunque haya pasado su hora.

🧭 Cómo llega a ejecutarse una tarea programada
Diagrama explicativo
🔍 Situación
🌐
Petición de página
Una visita que ejecuta WordPress
✕ No se ejecuta
→
🔎
Comprobar tareas pendientes
Si alguna tarea ya pasó su hora
✕ No comprueba
→
🔁
Petición de loopback
Servidor → su propio [wp-cron.php]
✕ 403
→
⚙️
Ejecutar la tarea
[wp-cron.php] procesa las tareas programadas
✓ Se ejecuta
Cuando llega una petición que ejecuta WordPress, se comprueban las tareas que ya pasaron su hora y el servidor llama a [wp-cron.php] en su propia dirección para procesarlas.
Si no hay visitas o se responde con un archivo de caché de página, WordPress no se ejecuta, así que las tareas ya vencidas esperan a la siguiente petición.
Si [DISABLE_WP_CRON] es true, no se comprueban las tareas aunque lleguen peticiones, y sin un cron del sistema no queda nada que las ejecute.
Si una regla de seguridad bloquea [wp-cron.php], la petición de loopback vuelve con un 403 y las tareas no se ejecutan.

1️⃣ Cuando no hay visitas o responde la caché de página

WP-Cron solo comprueba las tareas pendientes en peticiones que ejecutan WordPress, así que en las horas sin visitas las tareas vencidas se van acumulando. Aunque haya visitas, el resultado es el mismo si responde un archivo de caché de página, porque WordPress no se ejecuta.

En un WordPress con la caché de página de WP Rocket activada, abrir la página de inicio en caché no registró ninguna llamada a [wp-cron.php]. Al abrir una URL sin caché se registró una llamada en el mismo segundo y se ejecutaron las cinco tareas atrasadas.

Puedes ver las tareas atrasadas filtrando la lista de WP-CLI por las filas cuyo [next_run_relative] es [now].

wp cron event list --next_run_relative=now --fields=hook,next_run_gmt,next_run_relative
+----------------------------------+---------------------+-------------------+
| hook                             | next_run_gmt        | next_run_relative |
+----------------------------------+---------------------+-------------------+
| rocket_saas_pending_jobs         | 2026-10-17 14:49:57 | now               |
| action_scheduler_run_queue       | 2026-10-17 14:49:57 | now               |
| action_scheduler_run_queue_rucss | 2026-10-17 14:49:58 | now               |
| rocket_saas_on_submit_jobs       | 2026-10-17 14:49:58 | now               |
| rocket_preload_process_pending   | 2026-10-17 14:49:59 | now               |
+----------------------------------+---------------------+-------------------+

[now] indica que la hora programada ya pasó. Este comando de lista también carga WordPress, así que si hay tareas atrasadas llama a [wp-cron.php] en cuanto termina. Si vuelves a ejecutar el mismo comando enseguida, las tareas que acababas de ver ya no están en la lista.

Para procesar las tareas atrasadas antes de corregir la causa, ejecuta al momento con WP-CLI solo las que ya vencieron.

wp cron event run --due-now
Executed the cron event 'rocket_saas_pending_jobs' in 0.005s.
Executed the cron event 'action_scheduler_run_queue' in 0.006s.
Executed the cron event 'action_scheduler_run_queue_rucss' in 0.006s.
Executed the cron event 'rocket_saas_on_submit_jobs' in 0.005s.
Executed the cron event 'rocket_preload_process_pending' in 0.007s.
Success: Executed a total of 5 cron events.

Este comando ejecuta las tareas dentro del servidor sin petición HTTP; para procesarlas a intervalos fijos sin depender de las visitas, registra el mismo comando en el cron del sistema.

2️⃣ Cuando solo está activado DISABLE_WP_CRON y no hay cron del sistema

Con [DISABLE_WP_CRON] en true, WP-Cron no comprueba las tareas pendientes aunque lleguen peticiones de página. La documentación oficial también indica registrar primero en el programador de tareas del sistema y después añadir esta constante; si solo añades la constante sin registrar nada, no queda nada que ejecute las tareas programadas.

Con la constante puesta, una entrada programada para algo más de un minuto después siguió como [Programada] una vez pasada la hora, y la columna de fecha de la lista de entradas mostró [Programación perdida]. Mientras tanto no se registró ni una sola llamada a [wp-cron.php].

Puedes comprobar si la constante está activa con [wp cron test].

wp cron test
Error: The DISABLE_WP_CRON constant is set to true. WP-Cron spawning is disabled.

Si aparece este error, comprueba si el cron del sistema tiene una línea que llame a [wp-cron.php] o que ejecute [wp cron event run]. Si el crontab de la cuenta del sitio está vacío, se muestra lo siguiente.

crontab -l
no crontab for example

Si no hay ninguna línea, registra un cron del sistema; si tu entorno no lo permite, borra la línea [DISABLE_WP_CRON] y vuelve a usar WP-Cron.

3️⃣ Cuando la petición de loopback del servidor está bloqueada

Cuando hay trabajo pendiente, WP-Cron hace que el servidor envíe una petición a [wp-cron.php] en la dirección de su propio sitio para ejecutar las tareas; esa es la petición de loopback. Si una regla de seguridad bloquea [wp-cron.php], la petición de loopback vuelve con un 403 y las tareas no se ejecutan.

En un servidor con Nginx y Apache, al restringir [wp-cron.php] para que solo se abra desde 127.0.0.1, la petición de loopback quedó bloqueada con un 403. Esto pasa porque la petición que el servidor envía a su propio dominio entra por la IP pública, y [wp cron test] devuelve el mismo código de estado.

wp cron test
Error: WP-Cron spawn returned HTTP status code: 403 Forbidden

Con las tareas más de cinco minutos atrasadas, al abrir la pantalla [Salud del sitio] aparecieron juntos en [Mejoras recomendadas] el aviso de loopback y el evento programado fallido.

Pestaña Estado de Salud del sitio con un evento programado fallido y un aviso de petición de loopback después de que la petición de loopback de WP-Cron se bloqueara con un 403

Al quitar la regla, [wp cron test] volvió a funcionar. Si necesitas mantenerla, ejecuta las tareas con WP-CLI desde el cron del sistema. La ejecución con WP-CLI no pasa por una petición HTTP, así que las tareas atrasadas se procesaron incluso con la misma regla activa.

🔢 FAQ & contenido recomendado

Las comprobaciones de actualizaciones [wp_version_check], [wp_update_plugins] y [wp_update_themes] se ejecutaban cada 12 horas en el sitio de pruebas. Vaciar la papelera ([wp_scheduled_delete]) y borrar transients caducados estaban registrados a diario, y la revisión de Salud del sitio, semanal. Vaciar la papelera borra para siempre las entradas y los comentarios que llevan más de 30 días (valor por defecto) en ella, y si WP-Cron no se ejecuta, estas tareas tampoco se ejecutan a su hora.

Es el hook con el que Action Scheduler, una biblioteca de colas de trabajos incluida en plugins, procesa los trabajos pendientes; en el sitio de pruebas estaba registrado cada minuto. El FAQ oficial de Action Scheduler indica que esta cola se inicia por defecto desde WP-Cron y al final de las peticiones del panel de administración (hook [shutdown]). En el sitio de pruebas con solo [DISABLE_WP_CRON] activado y sin cron del sistema, esta fila también quedó en [now] junto con la entrada programada.

Según la documentación oficial, existe una alternativa: poner la constante [ALTERNATE_WP_CRON] en true en [wp-config.php]. Cuando hay tareas que ejecutar, redirige la petición GET del visitante a la misma URL con un valor [doing_wp_cron] añadido. Así [wp-cron.php] se ejecuta dentro de la petición original, sin pasar por una petición de loopback. La misma documentación advierte que no es el comportamiento predeterminado de WordPress y conlleva riesgos, así que si puedes registrar un cron del sistema, úsalo primero.

🧭 Contenido recomendado: tareas programadas de WordPress 7 artículos · 4 referencias
🗂️ Tareas programadas de WordPress
📄 WP-Cron(wp-cron.php) 📄 Ajustes básicos de wp-config.php 📄 Salud del sitio de WordPress
📋 Configurar crontab 📄 Comando nice de Linux
📋 WP CLI: instalación y configuración 📄 Buscar patrones sincronizados: WP-CLI
📡 About Cron 📡 Eventos de WP Cron 📡 Entender la programación de cron 📡 Conectar WP-Cron al programador de tareas del sistema
No hay resultados.

ℹ️ 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.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Demuestra que eres humano: 10   +   4   =