WP-Cron в WordPress: как починить и мониторить

Обновлено 3 ноября 2026

У WordPress есть собственный планировщик — WP-Cron. Он публикует отложенные записи, отправляет письма WooCommerce, запускает плагины бэкапов и SEO и проверяет обновления. Только это не настоящий cron: он срабатывает, лишь когда кто-то открывает сайт. Поэтому у отложенных записей появляется «Пропущено расписание», а плагины бэкапов пропускают ночи. Решение — перевести его на системный cron и следить, что тот продолжает работать.

Почему WP-Cron пропускает запуски

Отключите встроенный запуск

Добавьте строку в wp-config.php выше /* That's all, stop editing! */:

define( 'DISABLE_WP_CRON', true );

Это только запрещает запускать WP-Cron при просмотре страниц. Запланированные события остаются, а выполнять их теперь будет системный cron.

Запускайте его из системного cron

Если на сервере есть WP-CLI, выполняйте наступившие события каждые пять минут от имени пользователя, которому принадлежат файлы сайта:

# crontab -e для пользователя сайта, например www-data
*/5 * * * * cd /var/www/example.com && /usr/local/bin/wp cron event run --due-now --quiet

Без WP-CLI, например на виртуальном хостинге, запрашивайте wp-cron.php через curl:

*/5 * * * * curl -fsS -m 60 -o /dev/null "https://example.com/wp-cron.php?doing_wp_cron"

WP-CLI лучше: он не зависит от веб-сервера, не ограничен таймаутом запроса, а по коду завершения видно, получилось ли.

Что запланировано

wp cron event list                 # все события, их хуки и следующий запуск
wp cron schedule list              # доступные интервалы
wp cron event run woocommerce_cleanup_sessions   # выполнить одно событие сейчас

В админке тот же список показывает бесплатный плагин WP Crontrol. События со следующим запуском в прошлом значат, что планировщик не работает.

WooCommerce и многие плагины ставят задачи в очередь Action Scheduler («Инструменты → Запланированные действия»), а она работает поверх WP-Cron. Если встанет WP-Cron, встанет и очередь: письма о заказах, продление подписок, вебхуки.

Алерт, если он остановится

Теперь расписание WordPress выполняет системный cron, значит, следить нужно за ним. Создайте в Heartcron проверку с периодом 5 минут и запасом, например, 10 минут, и добавьте пинг в строку:

*/5 * * * * cd /var/www/example.com && /usr/local/bin/wp cron event run --due-now --quiet; curl -fsS -m 10 --retry 3 -o /dev/null https://ping.heartcron.com/<uuid>/$?

Пинг передаёт код завершения WP-CLI: 0 — проверка в порядке, любой другой — алерт сразу. Если строка из crontab пропадёт, сайт переедут на другой сервер или PHP сломается после обновления, пинг не придёт, и алерт придёт после запаса времени. Один раз выполните команду вручную и убедитесь, что она завершается с кодом 0, в том числе когда наступивших событий нет: wp cron event run --due-now; echo $?.

Важные задачи — отдельно

Одна проверка говорит, что планировщик работает. Для задачи, пропуск которой действительно заметен, например ночного бэкапа или ежедневной выгрузки, заведите отдельную проверку и пингуйте её из самой задачи. В плагине или в functions.php темы:

add_action( 'my_nightly_export', function () {
    $url = 'https://ping.heartcron.com/<uuid>';
    wp_remote_get( $url . '/start', [ 'timeout' => 10 ] );
    try {
        my_run_export();
        wp_remote_get( $url, [ 'timeout' => 10 ] );
    } catch ( Throwable $e ) {
        wp_remote_post( $url . '/fail', [ 'timeout' => 10, 'body' => $e->getMessage() ] );
        throw $e;
    }
} );

Задайте проверке то же расписание, что у события. Не уверены, как записать его в формате cron? Расшифровщик cron-выражений покажет ближайшие запуски.

Другие руководства