- Как устроен WP-Cron
- Почему на VPS virtual cron — слабое место
- Когда переходить на system cron
- Пошагово: отключить pseudo-cron и включить system cron
- 1. Бэкап и staging
- 2. Отключить запуск cron из HTTP
- 3. System cron от пользователя веб-сервера
- 4. Защитить wp-cron.php снаружи (опционально)
- 5. Проверка после переключения
- WooCommerce и Action Scheduler
- Типичные ошибки
- Чеклист на первую неделю
- Итог
На shared-хостинге WordPress сам «просыпается» при заходе посетителя и дёргает wp-cron.php. На VPS с нормальным трафиком это ещё терпимо. На сайте с редкими визитами, агрессивным page cache или WooCommerce в фоне виртуальный cron начинает врать: рассылки опаздывают, Action Scheduler копит pending, формы «отправились», а письмо ушло через два часа.
Ниже — как отключить pseudo-cron, повесить system cron на wp cron event run, и не сломать Woo, membership и плагины рассылок.
Как устроен WP-Cron
WordPress не держит демон. При каждом запросе (если не отключён) ядро проверяет wp_options → cron и при наступлении времени в том же HTTP-запросе выполняет хуки: publish_future_post, очистка ревизий, задачи плагинов.
- Точка входа:
wp-cron.phpили встроенный вызов вwp-settings.php. - Расписание хранится в БД, не в crontab сервера.
- Плагины вешают свои события через
wp_schedule_event().
На бумаге удобно. На проде с cache и малым трафиком — ненадёжно.
к содержанию ↑Почему на VPS virtual cron — слабое место
| Ситуация | Что происходит |
|---|---|
| Page cache отдаёт HTML без PHP | Запрос не доходит до WP → cron не тикает |
| Ночью нет визитов | Задачи сдвигаются на утро |
| Долгая cron-задача в HTTP | Таймаут nginx/PHP-FPM, обрыв на полпути |
| DDoS / боты | Лишние срабатывания wp-cron.php в логах |
| Несколько инстансов WP | Гонки за одну таблицу cron (реже, но бывает) |
Связка с мониторингом аномалий: всплеск фоновых задач и wp_mail часто совпадает с «cron наконец догнал очередь».
Когда переходить на system cron
Делайте на VPS/dedicated, если:
- WooCommerce, подписки, LMS, newsletter-плагины с расписанием.
- Action Scheduler / WP-Cron events больше пары десятков.
- Включён полный page cache (nginx, LiteSpeed, Cloudflare APO).
- Уже видели «зависшие» scheduled posts или отложенные письма.
Можно оставить virtual cron, если:
- Лендинг без фоновых задач и трафик стабильный весь день.
- Shared-хостинг запрещает править crontab (тогда хотя бы мониторьте
wp cron event list).
Пошагово: отключить pseudo-cron и включить system cron
1. Бэкап и staging
Сначала на копии сайта. После переключения проверьте: оформление заказа, форму, отложенную публикацию, рассылку тестовым списком.
2. Отключить запуск cron из HTTP
В wp-config.php до строки /* That's all, stop editing! */:
define('DISABLE_WP_CRON', true);Не путать с удалением wp-cron.php — файл остаётся, просто ядро не стартует его на каждом хите.
3. System cron от пользователя веб-сервера
Узнайте путь к PHP и корню WP. Типичная строка в crontab -e (пользователь www-data или deploy):
*/5 * * * * cd /var/www/example.com && /usr/bin/php wp-cron.php > /dev/null 2>&1Или через WP-CLI (предпочтительно на VPS с CLI):
*/5 * * * * cd /var/www/example.com && /usr/bin/wp cron event run --due-now --path=/var/www/example.com > /dev/null 2>&1Интервал 5 минут — разумный дефолт. Раз в минуту — только если плагин требует (редко). Раз в 15 — рискуете опозданием Woo-задач.
к содержанию ↑4. Защитить wp-cron.php снаружи (опционально)
Раз HTTP-cron отключён, прямой вызов https://site/wp-cron.php ботами бессмысленен. В nginx:
location = /wp-cron.php {
allow 127.0.0.1;
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}System cron бьёт в CLI — этот блок режет только внешний шум.
5. Проверка после переключения
wp cron event list --fields=hook,next_run,recurrence
wp action-scheduler status # если WooCommerceСоздайте тестовый отложенный пост на +10 минут — должен выйти без ручного захода на сайт.
WooCommerce и Action Scheduler
Woo перевёл очереди на Action Scheduler — отдельные таблицы, свой воркер поверх cron-хуков.
Что проверить:
- Tools → Scheduled Actions — нет ли тысяч
pending/failed. - Хук
action_scheduler_run_queueдолжен попадать в расписание; без тикающего cron очередь растёт. - После
DISABLE_WP_CRONне отключайте system cron «на выходные» — заказы и письма встанут. - Тяжёлые импорты и sync-плагины — смотрите peak CPU; при необходимости вынесите
wp cron event runв отдельный low-traffic слот, но не реже 5 мин.
Если failed растёт аномально — это сигнал к SMTP, API маркетплейса или битому плагину, не к интервалу cron само по себе.
Типичные ошибки
DISABLE_WP_CRONбез system cron — тихая смерть всех фоновых задач.- Cron от root, файлы от www-data — permission denied, задачи «выполняются» в логе crontab, WP молчит.
- Неверный
--pathв WP-CLI — другая копия сайта или пустая установка. - Два crontab на один сайт — двойной запуск, дубли писем (редко, но неприятно).
- Забыли про staging — на тесте тоже отключили HTTP-cron, но не добавили system — «на стейдже всё сломалось».
- Плагин «Disable WP Cron» + ручной crontab — дублирующие плагины; оставьте один способ.
Чеклист на первую неделю
wp cron event list— нет просроченныхoverdueсобытий.- Action Scheduler:
pendingстабилен,failedне растёт. - Отложенная публикация и Woo order emails уходят вовремя.
- В access-логе нет сотен хитов
/wp-cron.phpс интернета (если закрыли nginx). - В runbook сервера записана строка crontab и путь к PHP/CLI.
- После деплоя плагинов — разовый
wp cron event run --due-nowна staging.
Итог
На VPS virtual WP-Cron — legacy-удобство, не продакшен-стратегия. Пара строк в wp-config.php и одна строка в crontab дают предсказуемый фон для Woo, форм и рассылок. Это логичное продолжение после Redis и мониторинга: сначала ускоряете и наблюдаете, потом убираете «случайный» запуск задач из визита бота.
Как у вас сейчас — чистый WP-Cron на хите или уже system cron? Напишите в комментариях на web7.pro — подскажу интервал под ваш стек.
Плагин рейтинга создан автором этого блога. Буду очень признателен, если вы сможете его поддержать (ссылка)



