Si vous avez déjà vu des pics CPU “inexplicables” toutes les 5 minutes, ou des emails WordPress qui partent en rafale après une période de creux, il y a de fortes chances que wp-cron soit en cause. Le problème vient rarement de WordPress lui-même : c’est le modèle “pseudo-cron” déclenché par les visites qui devient instable dès que le trafic n’est pas régulier, ou qu’un cache agressif (Varnish, Cloudflare, plugin de cache) coupe les requêtes.

Le besoin / Le problème serveur

WordPress 6.9.4 (avril 2026) utilise toujours WP-Cron : un planificateur de tâches qui s’exécute quand quelqu’un charge une page. En coulisses, WordPress fait une requête HTTP vers wp-cron.php pour traiter des événements planifiés (publication programmée, vérifications de mises à jour, envois d’emails, actions WooCommerce, sauvegardes, etc.).

Sur un serveur “réel”, ce modèle a trois effets que j’ai souvent observés sur des sites avec cache et peu de trafic :

  • Tâches en retard : si personne ne visite, rien ne s’exécute.
  • Effet “rattrapage” : au premier hit après 2h, WordPress tente d’exécuter un paquet d’événements d’un coup.
  • Surconsommation : si vous avez beaucoup de trafic, wp-cron peut se déclencher trop souvent (voire en parallèle), surtout si la requête loopback est lente.

À la fin, vous saurez :

  • désactiver le déclenchement “par visites” via DISABLE_WP_CRON,
  • configurer un cron serveur fiable (WP-CLI),
  • protéger wp-cron.php pour éviter les abus,
  • vérifier que les événements s’exécutent bien et diagnostiquer les échecs.

Résumé rapide

  • Ajoutez define('DISABLE_WP_CRON', true); dans wp-config.php pour couper le déclenchement automatique.
  • Créez un cron système qui exécute wp cron event run --due-now toutes les 1 à 5 minutes.
  • Évitez l’appel HTTP direct à wp-cron.php quand WP-CLI est possible (moins fragile, plus observable).
  • Bloquez/limitez l’accès public à /wp-cron.php (Nginx/Apache) tout en autorisant votre cron.
  • Vérifiez avec wp cron event list, les logs PHP-FPM/nginx/apache, et un curl ciblé.

Avant de commencer (prérequis)

Accès et outils :

  • SSH sur le serveur (ou au minimum une console).
  • WP-CLI disponible côté serveur (idéalement wp dans le PATH).
  • Accès au fichier wp-config.php.
  • Accès aux logs : PHP-FPM, Nginx ou Apache, et éventuellement systemd journal.

Sauvegarde obligatoire (production) :

  • Fichiers WordPress + base de données. Ne testez pas ça “en live” sans rollback possible.

Versions recommandées (alignées avec WordPress 6.9.4) :

  • PHP 8.1+ (8.2/8.3 très courant en 2026).
  • MySQL 8+ ou MariaDB 10.6+.
  • Nginx ou Apache, avec HTTPS.

Sources officielles utiles :

Étape 1 : Comprendre ce que fait vraiment wp-cron (et pourquoi ça dérape)

WP-Cron n’est pas un daemon. C’est une liste d’événements stockés en base (option cron dans la table wp_options), exécutés quand WordPress a une opportunité. L’opportunité, par défaut, c’est une visite.

Voici ce qui se passe classiquement :

  • Un visiteur charge une page.
  • WordPress détecte des événements “dus”.
  • WordPress déclenche une requête HTTP “loopback” vers /wp-cron.php (non bloquante) pour exécuter les tâches.

Les deux causes de panne les plus fréquentes que je rencontre :

  • Loopback cassé : DNS interne, pare-feu, header Host, règle WAF, ou wp-cron.php bloqué par un plugin sécurité.
  • Cache/proxy : le site sert des pages depuis Varnish/Cloudflare, donc WordPress ne “voit” pas les hits et le cron dérive.

Quand vous passez sur un cron serveur, vous remplacez “déclenché par des visites” par “déclenché par le système”, ce qui rend les exécutions prévisibles et traçables.

Étape 2 : Désactiver wp-cron.php côté WordPress (proprement)

Objectif : empêcher WordPress de lancer des loopbacks à chaque hit. Vous gardez WP-Cron comme planificateur, mais vous externalisez le déclenchement.

Éditez wp-config.php et ajoutez la constante DISABLE_WP_CRON avant la ligne “stop editing”. C’est une erreur réaliste : beaucoup de gens la collent après, et elle ne prend pas effet.

<?php
/**
 * Configuration WordPress - extrait pertinent pour WP-Cron
 * Compatible WordPress 6.9.4+ et PHP 8.1+
 */

/* ... vos constantes existantes ... */

/**
 * Désactive le déclenchement automatique de WP-Cron par les visites.
 * Les événements restent planifiés, mais ne s’exécutent plus sans cron serveur.
 */
define('DISABLE_WP_CRON', true);

/* C’est tout, ne touchez pas à ce qui suit. */
if ( ! defined('ABSPATH') ) {
	define('ABSPATH', __DIR__ . '/');
}

require_once ABSPATH . 'wp-settings.php';

Résultat attendu : les tâches planifiées ne se déclenchent plus “toutes seules”. Si vous ne configurez pas le cron serveur, vous verrez rapidement des posts programmés qui ne publient pas, ou des actions WooCommerce en retard.

Option utile : réduire la tentation des “rattrapages”

Si vous avez un site qui a accumulé des événements en retard, vous pouvez d’abord faire un rattrapage contrôlé via WP-CLI (voir étape 3), puis seulement après activer le cron système.

Étape 3 : Mettre en place un vrai cron serveur (WP-CLI recommandé)

Deux approches existent :

  • Requête HTTP vers wp-cron.php (simple, mais fragile et plus exposée).
  • WP-CLI : exécute directement WordPress en CLI (plus fiable, meilleure observabilité, pas de dépendance loopback).

En 2026, sur la plupart des VPS et hébergements sérieux, WP-CLI est disponible. Je privilégie WP-CLI à chaque fois que possible.

3.1 Identifier le bon utilisateur système

Votre cron doit tourner avec le même utilisateur que PHP-FPM/les fichiers WordPress (souvent www-data sur Debian/Ubuntu). Sinon, vous finissez avec des fichiers créés en root, des permissions cassées, ou des caches impossibles à purger.

# Vérifiez l’utilisateur du webserver (exemples)
ps aux | grep -E 'php-fpm|apache2|nginx' | head

# Vérifiez le propriétaire du dossier WordPress
cd /var/www/site
ls -la | head

3.2 Tester WP-CLI manuellement (avant de cronifier)

Placez-vous dans le répertoire WordPress (là où se trouve wp-config.php), puis listez les événements.

cd /var/www/site

# Liste des événements (les plus proches en premier)
wp cron event list --fields=hook,next_run_relative,next_run_gmt,recurrence --orderby=next_run_gmt --order=asc

Exécutez ensuite les événements “dus maintenant” :

# Exécute uniquement les événements arrivés à échéance
wp cron event run --due-now --quiet

# Variante verbeuse (utile en debug)
wp cron event run --due-now

Si vous avez des erreurs PHP fatales, vous les verrez ici, ce qui est déjà un gros avantage par rapport à wp-cron déclenché en HTTP (où les erreurs se perdent souvent).

3.3 Crontab classique (recommandé)

Éditez la crontab de l’utilisateur web (www-data le plus souvent). Sur Debian/Ubuntu :

# Ouvre la crontab de www-data
sudo crontab -u www-data -e

Ajoutez une ligne (toutes les 2 minutes est un bon compromis sur la majorité des blogs ; 1 minute pour WooCommerce/adhésions ; 5 minutes pour un blog tranquille) :

*/2 * * * * cd /var/www/site && /usr/bin/wp cron event run --due-now --quiet --path=/var/www/site >> /var/log/wp-cron.log 2>&1

Notes pratiques :

  • Chemin WP-CLI : adaptez /usr/bin/wp (faites which wp).
  • –path : redondant si vous faites cd, mais je le garde, ça évite des surprises.
  • Logs : /var/log/wp-cron.log doit être accessible en écriture par l’utilisateur (ou utilisez syslog).

3.4 Alternative systemd timer (plus propre que cron sur certains serveurs)

Si votre serveur est géré via systemd, un timer vous donne des logs centralisés (journalctl) et une meilleure gestion des échecs. C’est très pratique en staging/production.

# Fichier service
sudo tee /etc/systemd/system/wp-cron.service > /dev/null <<'EOF'
[Unit]
Description=WordPress cron via WP-CLI (due-now)

[Service]
Type=oneshot
User=www-data
Group=www-data
WorkingDirectory=/var/www/site
ExecStart=/usr/bin/wp cron event run --due-now --path=/var/www/site
# Commentaire : vous pouvez ajouter --quiet si vous voulez moins de bruit
EOF

# Fichier timer
sudo tee /etc/systemd/system/wp-cron.timer > /dev/null <<'EOF'
[Unit]
Description=Exécute WP-Cron toutes les 2 minutes

[Timer]
OnBootSec=60s
OnUnitActiveSec=120s
AccuracySec=10s
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now wp-cron.timer
sudo systemctl list-timers | grep wp-cron

Résultat attendu : le timer déclenche le service régulièrement, et vous pouvez lire les sorties via :

sudo journalctl -u wp-cron.service --since "1 hour ago" --no-pager

Compatibilité Divi 5 / Elementor / Avada

Ces page builders n’ont pas besoin d’un cron spécifique pour “afficher” vos pages. En revanche, leurs écosystèmes (mises à jour, bibliothèques, modules, tâches de maintenance) s’appuient parfois sur WP-Cron comme n’importe quel plugin. Le passage à un cron serveur améliore généralement la stabilité des tâches de maintenance, surtout sur des sites Elementor + cache serveur.

Étape 4 : Protéger l’endpoint wp-cron.php (anti-abus) sans casser le cron serveur

Quand vous désactivez WP-Cron côté WordPress, wp-cron.php reste accessible publiquement. Un bot peut le marteler, et vous recréez la charge que vous cherchiez à éviter.

Le but : bloquer l’accès public à /wp-cron.php tout en permettant votre mécanisme (WP-CLI n’a pas besoin de cet endpoint).

Cas 1 : vous utilisez WP-CLI (idéal) → vous pouvez bloquer totalement wp-cron.php

Avec Nginx, vous pouvez refuser l’accès :

# À placer dans le server {} (voir section "Fichiers complets" pour un exemple)
location = /wp-cron.php {
	deny all;
	return 403;
}

Avec Apache (.htaccess), vous pouvez faire :

# À placer dans .htaccess (voir section dédiée pour un fichier complet)
<Files "wp-cron.php">
	Require all denied
</Files>

Attention : si un plugin appelle explicitement wp-cron.php en HTTP (rare mais ça existe), il cassera. Dans mon expérience, c’est surtout le cas de vieux plugins ou de bouts de code copiés d’anciens tutoriels.

Cas 2 : vous déclenchez wp-cron.php en HTTP → autorisez uniquement votre IP

Si vous êtes sur un hébergement où WP-CLI est impossible, vous pouvez sécuriser par IP (ou par token), mais c’est moins propre.

Nginx (autoriser IP fixe, refuser le reste) :

location = /wp-cron.php {
	allow 203.0.113.10;   # Commentaire : IP de votre serveur de cron
	deny all;
	include fastcgi_params;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

Apache (.htaccess) :

<Files "wp-cron.php">
	Require ip 203.0.113.10
</Files>

Si votre IP n’est pas fixe (cron depuis un service externe), préférez WP-CLI ou un token dans l’URL + règles serveur strictes. Évitez de laisser wp-cron.php ouvert “au monde”.

Étape 5 : Régler la fréquence, les timeouts et le comportement sous charge

La fréquence “par défaut” qu’on voit partout (toutes les 5 minutes) n’est ni bonne ni mauvaise. Elle dépend de vos tâches. Sur un blog classique, 5 minutes passe. Sur WooCommerce, LMS, membership, ou gros site avec emails transactionnels, 1 minute est souvent plus réaliste.

5.1 Choisir une fréquence raisonnable

  • Blog vitrine : toutes les 5 minutes.
  • Blog avec newsletter / automatisations : toutes les 2 minutes.
  • WooCommerce / réservations : toutes les 1 minute (et surveillez).

5.2 Éviter les exécutions concurrentes

Sur des serveurs chargés, vous pouvez avoir deux runs qui se chevauchent (un cron démarre alors que le précédent n’a pas fini). WP-Cron a un mécanisme de lock, mais il n’empêche pas tous les scénarios quand les timeouts sont mal réglés ou quand le stockage objet est exotique.

Une approche simple côté cron : ne lancez pas une nouvelle exécution si une instance tourne déjà. Exemple avec flock :

*/2 * * * * /usr/bin/flock -n /tmp/wp-cron.lock sh -lc 'cd /var/www/site && /usr/bin/wp cron event run --due-now --quiet --path=/var/www/site' >> /var/log/wp-cron.log 2>&1

J’ai souvent vu cette ligne régler des “pics” aléatoires sur des serveurs mutualisés un peu lents.

5.3 Timeouts PHP et mémoire

Si vos événements font des appels API externes, des imports, ou des envois d’emails en lot, vous allez heurter :

  • max_execution_time (CLI vs FPM : différent selon config)
  • memory_limit

WP-CLI exécute PHP en CLI, donc il utilise souvent un php.ini différent de PHP-FPM. Vérifiez :

php -i | grep -E 'Loaded Configuration File|memory_limit|max_execution_time'
/usr/bin/wp --info

Si nécessaire, vous pouvez forcer des valeurs pour WP-CLI via des variables d’environnement ou un ini spécifique, mais évitez de masquer un bug (boucle infinie, requête lente) en augmentant tout “au hasard”.

5.4 Nettoyer les événements “fantômes” (staging/migrations)

Après une migration ou un staging cloné, j’ai souvent vu des événements planifiés par d’anciens plugins (désinstallés) qui restent et génèrent des erreurs. Listez les hooks :

wp cron event list --fields=hook,recurrence,next_run_gmt --orderby=hook --order=asc | head -n 50

Supprimez un événement précis (à faire avec prudence) :

# Exemple : supprime tous les événements d’un hook (dangereux si vous vous trompez)
wp cron event delete my_plugin_hook_name --all

Quand vous ne connaissez pas l’origine d’un hook, cherchez dans le code :

cd /var/www/site
grep -R --line-number "my_plugin_hook_name" wp-content/plugins wp-content/themes | head

Fichiers de configuration complets

Les exemples ci-dessous sont des bases “propres” orientées cron. Adaptez les chemins, sockets PHP-FPM, domaines, et règles existantes. Ne collez pas un fichier complet sur un serveur déjà en prod sans relire : c’est une erreur classique, et ça casse plus souvent Nginx que WordPress.

wp-config.php (extrait complet pertinent)

<?php
/**
 * wp-config.php - extrait orienté WP-Cron
 * WordPress 6.9.4+ / PHP 8.1+
 */

/** Désactive WP-Cron déclenché par les visites */
define('DISABLE_WP_CRON', true);

/** Exemple : désactive l’éditeur de fichiers en admin (bonus sécurité) */
define('DISALLOW_FILE_EDIT', true);

/* Vous gardez vos réglages DB, salts, etc. ici... */

if ( ! defined('ABSPATH') ) {
	define('ABSPATH', __DIR__ . '/');
}

require_once ABSPATH . 'wp-settings.php';

.htaccess (Apache) — bloquer wp-cron.php

# .htaccess - extrait compatible Apache 2.4+
# Objectif : bloquer l’accès public à wp-cron.php si vous utilisez WP-CLI côté serveur.

# WordPress rules (exemple minimal, conservez les vôtres)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# Bloque wp-cron.php
<Files "wp-cron.php">
	Require all denied
</Files>

nginx.conf (server block) — bloquer wp-cron.php

# Nginx server block - exemple minimal
# Objectif : exécuter WordPress et bloquer /wp-cron.php (si WP-CLI déclenche le cron)

server {
	listen 443 ssl http2;
	server_name example.com www.example.com;

	root /var/www/site;
	index index.php;

	# Logs
	access_log /var/log/nginx/example.access.log;
	error_log  /var/log/nginx/example.error.log;

	# Bloque wp-cron.php (WP-CLI n’en a pas besoin)
	location = /wp-cron.php {
		deny all;
		return 403;
	}

	# WordPress
	location / {
		try_files $uri $uri/ /index.php?$args;
	}

	# PHP-FPM
	location ~ .php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php8.3-fpm.sock;

		# Sécurité basique
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	}

	# Bloque l’exécution de PHP dans uploads (classique)
	location ~* ^/wp-content/uploads/.*.php$ {
		deny all;
	}
}

php.ini (CLI ou FPM) — réglages utiles pour cron

Vous n’avez pas toujours la main sur un php.ini global. Si vous l’avez, ces valeurs évitent des erreurs fréquentes sur des tâches lourdes. Ne montez pas tout à l’extrême sans raison.

; php.ini - extrait (à adapter)
; Commentaire : WP-CLI utilise souvent le php.ini CLI, différent de FPM

memory_limit = 256M
max_execution_time = 120
default_socket_timeout = 30

Vérification

Vous voulez vérifier trois choses : (1) WP-Cron auto est bien désactivé, (2) le cron serveur tourne, (3) les événements s’exécutent réellement.

1) Vérifier que DISABLE_WP_CRON est actif

cd /var/www/site
wp eval 'var_export( defined("DISABLE_WP_CRON") ? DISABLE_WP_CRON : null ); echo PHP_EOL;'

Résultat attendu : true.

2) Vérifier que votre cron exécute des événements

Lancez manuellement :

cd /var/www/site
wp cron event run --due-now

Puis vérifiez la liste :

wp cron event list --fields=hook,next_run_relative,recurrence --orderby=next_run_gmt --order=asc | head -n 30

3) Vérifier que wp-cron.php est bien bloqué (si vous l’avez bloqué)

curl -I https://example.com/wp-cron.php

Résultat attendu : 403. Si vous obtenez 200, votre règle serveur ne s’applique pas (mauvais vhost, cache, ou config non rechargée).

4) Vérifier le cron système

Crontab :

sudo crontab -u www-data -l

systemd timer :

sudo systemctl status wp-cron.timer --no-pager
sudo journalctl -u wp-cron.service --since "30 min ago" --no-pager

Tableau de diagnostic rapide

Symptôme Cause probable Vérification Solution
Tâches en retard, posts programmés non publiés WP-Cron désactivé mais pas de cron serveur wp eval + crontab -l Ajoutez le cron WP-CLI (toutes 1–5 min)
Charge CPU régulière, pics toutes les minutes Cron trop fréquent + événements lourds wp cron event run --due-now + logs Augmentez l’intervalle, optimisez l’événement, ajoutez flock
curl /wp-cron.php retourne 200 Règle Nginx/Apache non appliquée Vérifiez vhost actif + reload Corrigez le bon server block, rechargez le service
WP-CLI échoue (DB, PHP fatal) Chemin, user, ou config CLI différente wp --info, php -i, logs Exécutez en www-data, corrigez PATH, fixez le bug PHP
Événements en double Deux crons (HTTP + WP-CLI) tournent Vérifiez crontabs + services Supprimez l’un, gardez WP-CLI

Si ça ne marche pas

Quand le cron serveur “ne marche pas”, ce n’est presque jamais WordPress. C’est le chemin, l’utilisateur, ou un fatal error dans une tâche.

1) Valider le contexte d’exécution

Testez en forçant l’utilisateur web :

sudo -u www-data -H bash -lc 'cd /var/www/site && /usr/bin/wp --info'
sudo -u www-data -H bash -lc 'cd /var/www/site && /usr/bin/wp cron event run --due-now'

Erreurs typiques :

  • “Could not open input file: wp” → WP-CLI pas dans le PATH du cron.
  • “Error establishing a database connection” → mauvais --path ou mauvais répertoire.
  • Fatal error PHP → plugin/thème casse en CLI (souvent du code qui suppose $_SERVER ou un contexte HTTP).

2) Consulter les logs au bon endroit

Selon votre stack :

  • Nginx : /var/log/nginx/*.error.log
  • Apache : /var/log/apache2/error.log
  • PHP-FPM : /var/log/php8.x-fpm.log ou journal systemd
  • systemd timer : journalctl -u wp-cron.service
  • Votre log cron dédié : /var/log/wp-cron.log
# Exemples
tail -n 200 /var/log/wp-cron.log
sudo tail -n 200 /var/log/nginx/example.error.log
sudo journalctl -u wp-cron.service --since "2 hours ago" --no-pager

3) Identifier l’événement qui bloque

Exécutez un hook spécifique (au lieu de tout lancer) pour isoler :

# Listez d’abord les hooks
wp cron event list --fields=hook,next_run_gmt --orderby=next_run_gmt --order=asc | head -n 50

# Puis lancez un hook précis (exemple)
wp cron event run wp_version_check

Si un hook plante, corrigez le plugin/thème responsable. Évitez l’anti-pattern : “augmenter la mémoire” pour masquer un fatal error.

4) Vérifier que vous n’avez pas un cache qui “court-circuite” des URLs internes

Si vous aviez auparavant un cron HTTP, un WAF/CDN peut bloquer wp-cron.php. Avec WP-CLI, ce problème disparaît. Si vous devez rester en HTTP, autorisez l’URL côté WAF et limitez par IP.


Pièges et erreurs courantes

Erreur Cause Solution
Ajout de DISABLE_WP_CRON après “stop editing” La constante n’est jamais chargée Placez-la avant le chargement de wp-settings.php
Tester sur production sans sauvegarde Un cron mal réglé peut déclencher des tâches lourdes en boucle Snapshot + export DB, test en staging si possible
Deux crons actifs (wp-cron auto + cron serveur) Oubli de désactiver wp-cron, ou ancien cron HTTP toujours présent Activez DISABLE_WP_CRON et supprimez l’autre déclencheur
WP-CLI fonctionne en SSH, pas via cron PATH différent, environnement minimal de cron Utilisez le chemin absolu (/usr/bin/wp) et --path
Fichiers créés en root Cron exécuté en root Exécutez en www-data (ou user du site)
Snippet d’ancien tutoriel : appel HTTP à wp-cron.php?doing_wp_cron=... Copié/collé d’anciennes pratiques, fragile avec CDN/WAF Préférez wp cron event run --due-now via WP-CLI
Blocage de wp-cron.php et tâches qui disparaissent Un plugin dépend d’un appel HTTP direct Réautorisez temporairement, migrez le plugin, ou déclenchez via WP-CLI

Sécurité serveur

Le cron est un point d’entrée indirect : il exécute du code plugin/thème de façon non interactive. Si un attaquant peut déclencher wp-cron.php à volonté, il peut amplifier une charge ou exploiter un plugin vulnérable plus facilement.

  • Bloquez wp-cron.php si vous utilisez WP-CLI (recommandé).
  • Limitez par IP si vous devez appeler wp-cron.php en HTTP.
  • Exécutez le cron avec un utilisateur non privilégié (jamais root).
  • Surveillez les logs : une hausse de hits sur /wp-cron.php est un signal d’abus.
  • Gardez WordPress et plugins à jour : WP-Cron exécute leurs hooks, donc une vulnérabilité dans un hook cron est une vulnérabilité tout court.

Pour aller plus loin côté headers (hors sujet direct cron, mais souvent fait au même moment), vous pouvez vous inspirer des recommandations serveur générales, en restant prudent pour ne pas casser l’admin. Si vous mettez en place une politique CSP stricte, testez l’éditeur de blocs et les builders (Divi 5, Elementor, Avada) en staging.

Ressources

FAQ

Dois-je désactiver wp-cron sur tous mes sites ?

Sur un site avec SSH/WP-CLI et un minimum de contrôle serveur, oui, presque systématiquement. Sur un mutualisé sans cron fiable, non : vous risquez surtout d’avoir des tâches qui ne tournent plus.

Quel intervalle choisir pour le cron serveur ?

2 minutes est un bon point de départ. 5 minutes pour un blog simple, 1 minute pour des sites transactionnels. Si vous constatez des runs longs, ajoutez flock et optimisez les hooks lourds.

Est-ce que bloquer wp-cron.php peut casser quelque chose ?

Oui, si un plugin déclenche volontairement wp-cron.php en HTTP. C’est rare sur des plugins modernes, mais je l’ai déjà vu. Testez en staging et surveillez les logs après blocage.

Pourquoi WP-CLI est préférable à un curl vers wp-cron.php ?

Parce que vous supprimez la dépendance loopback (DNS/SSL/WAF), vous récupérez des erreurs visibles, et vous réduisez l’exposition publique de l’endpoint. C’est aussi plus simple à auditer.

Comment savoir quelles tâches sont planifiées ?

Utilisez wp cron event list. C’est le moyen le plus rapide côté serveur, sans dépendre d’un plugin d’admin.

Je vois des événements qui se répètent et ne disparaissent jamais. Normal ?

Oui pour les événements récurrents. Non si vous voyez des centaines d’événements identiques “dus” depuis longtemps : c’est souvent un hook qui plante avant de terminer, ou un cron serveur qui ne tourne pas.

Mon cron tourne, mais certaines tâches échouent en CLI alors qu’elles marchent en web.

Classique. Le code suppose parfois un contexte HTTP (variables $_SERVER, cookies, headers). Corrigez le plugin/thème : un hook cron ne devrait pas dépendre d’un navigateur.

Peut-on exécuter WP-Cron via systemd plutôt que cron ?

Oui, et c’est souvent mieux pour l’observabilité. Vous gagnez journalctl, des statuts clairs, et une gestion plus robuste des redémarrages.

Dois-je vider un cache après avoir changé wp-config.php ?

Si vous avez OPcache et un déploiement particulier, parfois oui. Dans le doute, redémarrez PHP-FPM proprement et purgez le cache applicatif si vous en avez un. Beaucoup de “ça ne marche pas” viennent d’un OPcache qui sert l’ancien fichier.

Est-ce lié aux permaliens ou à l’éditeur de blocs ?

Non. Les permaliens n’influencent pas WP-Cron. En revanche, des plugins liés à l’éditeur (ou des builders) peuvent planifier des tâches de maintenance ; le cron serveur les rend juste plus régulières.