WP-Cron в WordPress запускается не по расписанию операционной системы, а при заходе посетителя на сайт: файл wp-cron.php дергается на каждой загрузке страницы и проверяет, не пора ли выполнить отложенную задачу. На сайте с редкими визитами публикация по расписанию и рассылки опаздывают на часы. Разберем, как это исправить системным cron.
Почему WP-Cron опаздывает или не срабатывает вовсе
Псевдокрон WordPress жив только пока есть трафик: нет визита — нет проверки задач. Вторая причина сбоев — общий хостинг с агрессивным кэшированием страниц: кэширующий плагин отдает сохраненную HTML-копию и не пропускает запрос до PHP, а значит и до wp-cron.php. Третья причина — заблокированный на уровне сервера исходящий self-запрос, из-за которого WordPress не может сам себя дернуть по HTTP.
Как проверить текущее состояние задач
Список запланированных задач и их точное время удобно смотреть через WP-CLI, если он доступен на хостинге.
wp cron event list --fields=hook,next_run_relative,recurrence
Если колонка next_run_relative показывает отрицательное значение вроде «-3 hours», задача просрочена и ждет следующего визита посетителя, чтобы выполниться.
Как отключить встроенный псевдокрон
Отключение выполняется одной константой в wp-config.php — добавьте строку перед пометкой «That's all, stop editing!».
<?php
define('DISABLE_WP_CRON', true);
После этой правки WordPress перестает проверять задачи при каждом визите, но сами задачи из базы никуда не исчезают — их запуск просто ждет внешнего триггера.
Как настроить системный cron вместо псевдокрона
Задачу нужно передать планировщику самой операционной системы. Добавьте строку через crontab -e от имени пользователя, под которым работает сайт.
*/5 * * * * curl -s https://site.example/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Запуск раз в 5 минут — разумный компромисс для большинства сайтов: рассылки и публикации по расписанию не опаздывают заметно, а нагрузка на сервер остается небольшой. Если на сервере есть WP-CLI, вызов через него надежнее — минует HTTP-слой и не зависит от кэша страниц.
*/5 * * * * cd /var/www/site.example/public_html && wp cron event run --due-now --quiet
Как выбрать интервал для разных задач
| Задача | Рекомендуемый интервал | Последствие опоздания |
|---|---|---|
| Отложенная публикация записи | 1–5 минут | материал выходит позже плана |
| Плановая рассылка писем | 5 минут | письма уходят пачкой с задержкой |
| Очистка временных данных плагинов | 15–30 минут | растет размер базы данных |
| Проверка обновлений ядра и плагинов | 1 раз в час | задержка уведомления об обновлении |
Частые ошибки при переходе на системный cron
Забытая константа DISABLE_WP_CRON приводит к дублированию: задачи выполняются и по системному расписанию, и по старому псевдокрону при визите, из-за чего письма рассылки могут уйти дважды. Вторая ошибка — cron настроен на сервере, но у сайта включен LiteSpeed Cache или похожий плагин, который кэширует сам wp-cron.php как обычную страницу — исключите этот путь из правил кэша явно. Полный список действий при смене адреса и связанных с cron задач переноса описан в статье про смену домена WordPress.
Проверить, что перенос сработал, просто: через час после настройки системного cron снова выполните wp cron event list и убедитесь, что время в колонке next_run_relative сдвигается вперед даже без визитов на сайт. Для управления и диагностикой задач полезны и остальные команды — подборка собрана в статье про WP-CLI.
Итог
- WP-Cron по умолчанию запускается только при визите посетителя, поэтому на тихих сайтах задачи опаздывают.
- Отключить псевдокрон можно константой
DISABLE_WP_CRONвwp-config.php. - Задачу нужно передать в crontab операционной системы с интервалом 5 минут через curl или напрямую через WP-CLI.
- После переноса проверьте, что задачи не выполняются дважды из-за забытой константы.
- Кэширующие плагины стоит настроить так, чтобы они не отдавали
wp-cron.phpиз кэша.