Beaucoup de développeurs découvrent, souvent après coup, que le système de tâches planifiées de WordPress ne fonctionne pas comme un vrai cron système Unix. wp-cron.php ne s’exécute pas à intervalle fixe en arrière-plan : il se déclenche à chaque visite du site, qui vérifie alors si une tâche planifiée est en retard et l’exécute à ce moment-là. Sur un site à faible trafic, cela peut signifier qu’une tâche censée s’exécuter toutes les heures ne se déclenche en réalité qu’une fois par jour, au hasard des visites.
Cet article explique ce mécanisme en détail, et la configuration recommandée pour un site où la fiabilité de la planification compte réellement.
Comment fonctionne wp-cron par défaut
À chaque chargement de page, WordPress vérifie discrètement s’il existe des tâches planifiées en retard, via une requête asynchrone vers wp-cron.php. Si c’est le cas, ces tâches s’exécutent immédiatement, dans le contexte de cette requête. Ce système a un avantage (aucune configuration serveur nécessaire) et un inconvénient majeur : sans visite, rien ne se déclenche, jamais.
wp cron event list
Cette commande WP-CLI liste les tâches planifiées enregistrées, avec leur prochaine date d’exécution théorique. Sur un site avec peu de trafic, il n’est pas rare de constater des tâches en retard de plusieurs heures, voire plusieurs jours.
Planifier une tâche personnalisée
La fonction wp_schedule_event() enregistre une tâche récurrente, associée à un hook personnalisé :
add_action( 'init', function() {
if ( ! wp_next_scheduled( 'nettoyage_quotidien' ) ) {
wp_schedule_event( time(), 'daily', 'nettoyage_quotidien' );
}
} );
add_action( 'nettoyage_quotidien', function() {
// Logique de nettoyage à exécuter
} );
La vérification avec wp_next_scheduled() est indispensable : sans elle, chaque chargement de page où ce code s’exécute reprogrammerait la tâche, créant potentiellement des doublons.

Déclarer un intervalle personnalisé
WordPress ne propose nativement que hourly, twicedaily et daily. Pour un intervalle différent (toutes les quinze minutes, par exemple), le filtre cron_schedules permet d’en déclarer un nouveau :
add_filter( 'cron_schedules', function( $schedules ) {
$schedules['quinze_minutes'] = array(
'interval' => 15 * MINUTE_IN_SECONDS,
'display' => 'Toutes les 15 minutes',
);
return $schedules;
} );
Désactiver le déclenchement automatique et passer par un vrai cron
La solution la plus fiable pour un site où la ponctualité compte réellement (envoi d’emails programmés, synchronisation avec un système externe) consiste à désactiver le déclenchement automatique de wp-cron.php lors des visites, et à le remplacer par un vrai cron système :
define( 'DISABLE_WP_CRON', true );
Cette constante, à ajouter dans wp-config.php, empêche WordPress de vérifier les tâches en retard à chaque visite. Il faut alors configurer, côté serveur, une tâche cron réelle qui appelle wp-cron.php à intervalle régulier :
# Toutes les cinq minutes, via crontab
*/5 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Ou, de façon équivalente et souvent préférable, via WP-CLI, qui évite une requête HTTP complète et s’exécute directement en ligne de commande :
*/5 * * * * cd /var/www/monsite && wp cron event run --due-now --quiet
Tester une tâche sans attendre son déclenchement
Pour vérifier qu’une tâche fonctionne correctement sans attendre sa prochaine échéance théorique, WP-CLI permet de la déclencher manuellement :
wp cron event run nettoyage_quotidien
C’est un réflexe précieux en développement, qui évite de modifier temporairement l’intervalle de planification juste pour tester une logique.
Nettoyer les tâches orphelines
La désactivation d’un plugin laisse parfois des tâches planifiées actives, dont le hook associé n’existe plus. Ces tâches s’exécutent silencieusement sans rien faire, mais encombrent la liste et peuvent parfois provoquer des erreurs si le hook a réellement disparu. Un nettoyage périodique est recommandé :
wp cron event list --fields=hook,next_run_relative
wp cron event delete nom_du_hook_orphelin
Points de vigilance
- Toujours vérifier
wp_next_scheduled()avant de programmer une tâche récurrente - Désactiver
wp-cron.phppar défaut n’a de sens que si un vrai cron système prend le relais - Nettoyer les tâches orphelines après la désinstallation d’un plugin
- Éviter les tâches trop fréquentes et trop lourdes, qui peuvent surcharger un hébergement mutualisé
Un site vitrine à faible trafic, avec une tâche planifiée toutes les heures, peut très bien ne l’exécuter que deux fois par jour en pratique : la solution n’est jamais de multiplier les tentatives, mais de brancher un vrai cron.
En résumé
wp-cron rend un service réel pour des tâches peu critiques sur un site à trafic régulier, mais son fonctionnement basé sur les visites reste une source fréquente de déconvenues. Pour toute tâche dont la ponctualité compte, la combinaison DISABLE_WP_CRON et un vrai cron système reste la seule solution vraiment fiable.