Новинка Виртуальный VDS сервер в Нидерландах от 390р
Выберите продукт

WordPress: wp-cron vs real cron — как настроить и перестать терять задания

В WordPress планировщик задач работает не как системный cron: wp-cron запускается от посещений и зависит от HTTP-запросов. Разберём, почему задания задерживаются и «залипают», как диагностировать проблему и пошагово перевести сайт на системный cron без потерь.
WordPress: wp-cron vs real cron — как настроить и перестать терять задания

Если у вас на WordPress периодически «не уходят письма», не чистится кэш, не обновляются фиды, не срабатывают расписания резервных копий или «залипают» задачи WooCommerce — очень часто виноват не плагин, а wp-cron. Точнее, то, как он запускается.

В WordPress нет «настоящего» демона планировщика внутри PHP. Вместо этого используется механизм, который имитирует cron через входящие веб-запросы. Это удобно для shared-хостинга и простых сайтов, но на продакшене создаёт неожиданные эффекты: задания выполняются пачками, с задержками, дублируются или вообще не стартуют.

Ниже разберём: как устроен «крон» в WordPress, в чём разница между wp-cron и реальным системным cron, когда стоит переходить на cron на уровне ОС, и как сделать это безопасно.

Что такое wp-cron и почему он «не настоящий» cron

wp-cron — это встроенный планировщик задач WordPress. Он хранит расписания в базе (в опции cron) и выполняет callbacks, зарегистрированные ядром и плагинами.

Ключевая особенность: WordPress не имеет отдельного процесса, который «тикает» каждую минуту. Вместо этого он пытается запускать выполнение задач при каждом посещении сайта. Когда приходит HTTP-запрос, WordPress проверяет: есть ли просроченные события, и если да — инициирует обращение к wp-cron.php.

wp-cron — это не системный планировщик, а механизм, который пытается запускать задания «по случаю» входящих запросов.

Отсюда следуют практические последствия:

  • на сайте с низким трафиком задачи могут запускаться с большими задержками;
  • при всплеске трафика возможны конкурирующие запуски и «шторм» cron-процессов;
  • если сервер/защита ограничивает фоновые HTTP-запросы, задания могут не стартовать вообще;
  • в момент пиковых нагрузок cron добавляет ещё одну нагрузку на PHP/MySQL.

Как WordPress запускает wp-cron.php и где ломается

В типичной конфигурации WordPress инициирует обращение к wp-cron.php неблокирующим HTTP-запросом (например, через wp_remote_post()). Запрос идёт «сам в себя» по доменному имени сайта. И вот тут начинаются тонкости:

  • DNS/IPv6/прокси/CDN могут направлять запрос не туда, куда вы ожидаете;
  • WAF/правила безопасности иногда режут запросы к wp-cron.php;
  • мешают Basic Auth, IP allowlist или закрытая админка;
  • при проблемах с TLS (SNI/цепочка/истёкший сертификат) запрос не выполнится;
  • на слабых конфигурациях Nginx/Apache ↔ PHP-FPM это становится заметным источником нагрузки.

Real cron (системный cron) и что меняется для WordPress

Real cron — это системный планировщик на уровне ОС (cron/anacron/systemd timers), который запускает команду по расписанию независимо от посещаемости сайта. Для WordPress обычно делают так: отключают встроенный триггер wp-cron и запускают обработку задач по расписанию через системный планировщик.

Плюсы системного cron для WordPress:

  • Предсказуемость: задания выполняются близко к расписанию.
  • Контроль нагрузки: вы задаёте частоту, можно разнести по минутам разные сайты.
  • Стабильность: меньше шансов на пропуски из-за блокировок фоновых HTTP-запросов.
  • Диагностика: есть логи cron/systemd, проще понять, что запускается и с чем падает.

Минусы тоже есть:

  • нужен доступ к планировщику (на некоторых тарифах/хостингах это ограничено);
  • при нескольких сайтах на одном сервере важно не устроить одновременный пик запуска;
  • для очень нагруженных проектов иногда нужна более тонкая архитектура (очереди/воркеры).

Если вашему проекту уже тесно в рамках ограничений общего окружения, логичным шагом становится перенос на VDS, где вы контролируете cron/systemd, лимиты PHP-FPM и правила доступа к wp-cron.php.

Пример расписания crontab для запуска задач WordPress

Когда wp-cron достаточно, а когда пора переходить на системный cron

wp-cron обычно подходит для небольших сайтов с регулярным трафиком и простыми задачами: публикация запланированных постов, лёгкая очистка временных данных, обновление кеша раз в несколько часов.

Переход на системный cron почти всегда оправдан, если:

  • сайт с низкой посещаемостью, но есть критичные расписания (письма, синхронизации, платежи);
  • WooCommerce и фоновые действия (обработка заказов, вебхуки, очистка транзиентов);
  • есть интеграции, которые должны выполняться в конкретные окна времени;
  • наблюдаете «cron шторм»: много процессов wp-cron.php одновременно;
  • плагины добавляют тяжёлые задания (импорт/экспорт, генерация изображений, рассылки).

Для общего понимания, как устроены расписания на Linux (crontab и systemd timers) и как их правильно логировать, пригодится материал: cron, crontab и systemd timers: выбор и практика.

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды

Типичные симптомы проблем с wp-cron

На практике проблемы с wp-cron выглядят так:

  • Задержки: запланированные записи публикуются через 30–60 минут или «когда зайдёшь в админку».
  • Пачки: несколько часов ничего, потом внезапно массовое выполнение задач.
  • Дубли: одно и то же действие происходит дважды (например, повторная отправка письма).
  • Нагрузка: всплески CPU и одновременные PHP-процессы, совпадающие с входящим трафиком.
  • Очередь не разгребается: события копятся, в списке scheduled actions растёт «pending».

Диагностика: как понять, что ломается

Дальше — практичные проверки, которые обычно дают быстрый ответ.

1) Проверьте, не отключён ли wp-cron

В wp-config.php может быть включена константа отключения:

define('DISABLE_WP_CRON', true);

Если она включена, а системный cron при этом не настроен — задания выполняться не будут (или будут запускаться только вручную).

2) Проверьте, доступен ли wp-cron.php по HTTP именно с сервера

Важно не «открывается ли в браузере», а выполняется ли корректный запрос с самого хоста, где крутится сайт. Типовые проблемы:

  • редиректы HTTP→HTTPS или www↔non-www добавляют лишние переходы и иногда ломают запуск;
  • доступ закрыт по IP или Basic Auth;
  • CDN/WAF отвечает челленджем или 403;
  • нестабильный DNS или проблемы с IPv6.

3) Проверьте lock и конкуренцию

WordPress использует блокировку (lock), чтобы не запускать cron параллельно слишком часто. Но при высокой нагрузке и медленных задачах бывают ситуации, когда:

  • lock удерживается слишком долго из-за зависшего процесса;
  • происходит гонка и запускается несколько обработчиков;
  • процессы убиваются лимитами времени/памяти, и задания остаются «просроченными».

Если у вас в логах Nginx/Apache и PHP-FPM видно множество одновременных обращений к wp-cron.php — это прямой сигнал, что пора переводить на системный cron и ограничивать параллелизм.

4) WP-CLI: быстрая проверка событий

Если есть WP-CLI, диагностика становится проще:

wp cron event list

Можно принудительно запустить обработку просроченных задач:

wp cron event run --due-now

А чтобы понять, что «тяжёлое», смотрите конкретные хуки и их периодичность (часто виноваты плагины импорта/оптимизации/рассылок).

Как правильно перейти с wp-cron на системный cron

Переход делается в два шага: (1) отключить автозапуск wp-cron от посетителей, (2) настроить системный запуск по расписанию. Важно сделать это без окна, когда cron выключен «с двух сторон».

Шаг 1. Отключите встроенный триггер wp-cron

Добавьте в wp-config.php (обычно ближе к началу, до строки “That’s all…”):

define('DISABLE_WP_CRON', true);

Это отключит попытки WordPress запускать cron на каждом запросе.

Шаг 2. Настройте системный cron на запуск задач

Дальше есть два распространённых подхода: дергать wp-cron.php по HTTP или запускать WP-CLI. WP-CLI чаще надёжнее и быстрее, но не всегда доступен.

Вариант A (универсальный): запрос к wp-cron.php по HTTP

Пример для системного cron раз в 5 минут (команда должна быть одной строкой):

*/5 * * * * curl -fsS -m 30 -A 'cron' 'https://example.com/wp-cron.php?doing_wp_cron=1' >/dev/null

Пояснения по параметрам:

  • -f — считать HTTP 4xx/5xx ошибкой;
  • -sS — тише, но показать ошибки;
  • -m 30 — таймаут, чтобы не копились зависшие процессы;
  • User-Agent помогает отличать cron-запуски в логах.

Если сайт доступен только по Basic Auth или через фильтры WAF/CDN, этот вариант может потребовать отдельного разрешающего правила для wp-cron.php. В таких схемах часто проще перейти на WP-CLI.

Вариант B (предпочтительно при доступном WP-CLI): wp cron event run

Запуск через WP-CLI меньше зависит от сети/HTTPS/CDN и не делает лишний HTTP-круг. Пример раз в 5 минут:

*/5 * * * * cd /var/www/site && wp cron event run --due-now --quiet

Если WP-CLI запускается не от того пользователя, проверьте права на файлы и доступ к wp-config.php. Также убедитесь, что окружение (PATH, PHP) соответствует вашему воркеру.

Как выбрать частоту: каждую минуту или раз в 5 минут

Универсальный старт — раз в 5 минут. Раз в 1 минуту имеет смысл, если есть задачи, чувствительные к задержке, и при этом выполнение стабильно укладывается в лимиты.

Важно: если ваши задачи реально выполняются 2–3 минуты, а cron запускается каждую минуту, вы можете получить параллельные запуски и повторную нагрузку. Тогда лучше:

  • увеличить интервал (например, до 5 минут);
  • уменьшить время выполнения задач (оптимизация/разнос);
  • вынести тяжёлые процессы в воркеры/очереди на крупных проектах.

Практика: защита от параллельных запусков

Одна из главных целей системного cron — контролировать конкуренцию. На уровне cron это часто решают через блокировку.

Пример с flock (если запускаете WP-CLI):

*/5 * * * * flock -n /tmp/wp-cron.lock sh -lc 'cd /var/www/site && wp cron event run --due-now --quiet'

Так вы гарантируете, что новый запуск не начнётся, пока предыдущий ещё идёт (или просто пропустится, если lock занят).

Запуск WordPress cron через WP-CLI в консоли

Частые ошибки при настройке системного cron для WordPress

Ошибка 1. Отключили wp-cron, но не настроили cron в ОС

Самая распространённая. В итоге wp-cron выключен, а системный cron не запускает ничего — задания «умирают» полностью.

Ошибка 2. HTTP-запуск ходит через CDN/WAF и блокируется

Если используете вариант A, убедитесь, что запрос реально доходит до origin. Если у вас строгие политики доступа, иногда проще перевести запуск на WP-CLI, чем «пробивать» исключения на периметре.

Ошибка 3. Слишком частый cron и параллельные выполнения

Частота «каждую минуту» не всегда лучше. Стабильные 5 минут без параллелизма обычно эффективнее, чем 1 минута с очередями и дублями.

Ошибка 4. Неправильный домен и лишние редиректы

Если cron запускается через HTTP, используйте канонический URL без цепочек редиректов. Редиректы — это лишнее время, лишние ошибки и иногда неожиданные блокировки.

Как понять, что всё работает: контрольные признаки

После переключения на системный cron проверьте:

  • в логах web-сервера появились регулярные обращения к wp-cron.php (если вариант A);
  • или в логах cron/systemd есть успешные запуски WP-CLI (если вариант B);
  • запланированные записи публикуются вовремя;
  • очередь scheduled actions не растёт бесконечно;
  • исчезли всплески одновременных процессов wp-cron.php от трафика.

Если у вас cron-контур завязан на HTTPS и вы хотите заранее ловить ситуации с истёкшим сертификатом (когда фоновые запросы внезапно начинают падать), поможет материал: контроль срока действия SSL и продление без сюрпризов. А для надёжной цепочки доверия используйте нормальные SSL-сертификаты вместо временных решений.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Шпаргалка выбора: wp-cron или системный cron

  • Оставляйте wp-cron, если сайт маленький, трафик есть всегда, а задержка задач некритична.
  • Переходите на системный cron, если задачи критичны по времени, трафик нестабилен, есть WooCommerce/интеграции, или вы видите «cron шторм» и залипания.

Итого

wp-cron — компромиссный механизм, который хорошо подходит для простых сценариев и ограниченных окружений, но может подводить на продакшене. Перевод на системный cron — один из самых дешёвых по времени способов повысить стабильность WordPress: задачи начинают выполняться по расписанию, уменьшается хаотичная нагрузка, становится проще диагностика.

Если хотите, в следующем материале можно разобрать конкретные схемы: cron на виртуальном хостинге (без root), cron на VDS через systemd timers, и типовые настройки для WooCommerce/Action Scheduler.

Поделиться статьей

Вам будет интересно

MODX 3: ЧПУ на Apache и Nginx без 404 у вложенных страниц

MODX 3: ЧПУ на Apache и Nginx без 404 у вложенных страниц

Разберём, как направить ЧПУ-запросы в MODX 3, настроить сайт в корне домена или подкаталоге и проверить вложенные адреса. Инструкц ...
Критическая ошибка WordPress: восстановление после обновления

Критическая ошибка WordPress: восстановление после обновления

Если после обновления WordPress показывает сообщение о критической ошибке и не открывает панель управления, доступ можно вернуть б ...
WooCommerce: разбор зависших задач Action Scheduler через WP-CLI

WooCommerce: разбор зависших задач Action Scheduler через WP-CLI

Инструкция поможет найти причину зависшей очереди WooCommerce, проверить журналы Scheduled Actions, обработать просроченные задачи ...