Ускорение WordPress почти всегда упирается в кэширование, но «кэш» в WP — это несколько разных слоёв, которые легко перепутать. В итоге видим типичную картину: плагин кэша включён, а TTFB всё равно высокий; или объектный кэш включили, а сайт стал «жить своей жизнью» из‑за несогласованных TTL; или на распродаже/вирусном посте сервер падает от эффекта cache stampede.
Ниже — практичный разбор, как устроен wordpress cache в реальности: object cache (Redis/Memcached) и full page cache, какие задачи решает каждый слой, какие ловушки есть у wp-cron.php и admin-ajax.php, и как настроить систему так, чтобы она была быстрой и предсказуемой.
Два главных слоя: object cache и full page cache
Сильно упрощая, WordPress «тормозит» по двум причинам:
- он много раз повторяет одни и те же вычисления и запросы к базе данных;
- он генерирует HTML страницы на каждый запрос.
Эти причины перекрываются двумя слоями:
- Object cache — хранит результаты запросов/вычислений в памяти, чтобы PHP и MySQL делали меньше работы.
- Full page cache (страничный кэш) — хранит готовый HTML (или даже весь ответ), чтобы PHP не запускался вообще.
Object cache ускоряет «внутренности» WordPress, а full page cache в идеале убирает WordPress из цепочки для большинства гостевых запросов.
Object cache: что это и что именно кэшируется
Object cache в WP — это интерфейс, через который ядро и плагины складывают данные в кеш‑хранилище по ключу. Внутри это вызовы семейства функций wp_cache_get(), wp_cache_set(), wp_cache_delete() и т.п.
Кэшируются (зависит от ядра/темы/плагинов): результаты SQL-запросов, опции, результаты вычислений (например, разбор правил, сборка меню), фрагменты данных WooCommerce и многое другое. Если используется «персистентный» object cache, кэш живёт между запросами, а не только в рамках одного запуска PHP.
Redis object cache vs Memcached: что выбрать
И Redis, и Memcached решают задачу быстрого key-value кэша в RAM, но ведут себя по‑разному.
- Memcached — максимально простой и быстрый кэш «ключ‑значение». Нет персистентности, нет сложных структур, обычно минимальная операционная сложность. Хорош как «чистый кэш».
- Redis — богаче по возможностям: структуры данных, Lua-скрипты, репликация, разные режимы сохранения (RDB/AOF). Может быть и кэшем, и «мини‑БД» (это одновременно плюс и риск).
В контексте Redis object cache для WordPress чаще выбирают Redis, потому что:
- есть зрелые плагины и понятные режимы;
- проще контролировать TTL и политику вытеснения;
- удобно смотреть статистику и ключи при диагностике.
Но если вам нужна предельно простая схема и вы уверены, что нужен именно «одноразовый» кэш без накопления — Memcached тоже отличный вариант.
Если хотите глубже сравнить под PHP‑нагрузкой, полезно держать под рукой отдельный разбор: Memcached vs Redis для PHP и WordPress: где реально быстрее.

Если проект растёт и упирается в лимиты по CPU/RAM, обычно проще и предсказуемее держать Redis и PHP в изоляции на отдельной машине. Под такие задачи хорошо подходит VDS, где вы контролируете память, политику вытеснения Redis и параметры PHP-FPM без сюрпризов от соседей.
Типовые ожидания по эффекту от object cache
Object cache даёт максимум эффекта, когда:
- много повторяющихся запросов к базе (сложные темы, WooCommerce, большие каталоги);
- высокая доля авторизованных пользователей (админка, личные кабинеты), где full page cache часто ограничен;
- база данных на относительно медленном диске или перегружена.
Если у вас чисто контентный блог и 95% трафика — гости, то эффект от object cache может быть умеренным: основную экономию даст full page cache.
Full page cache: когда он «включает турбо»
Full page cache — это кэширование целого ответа. В идеальном сценарии запрос гостя отрабатывается так:
- веб‑сервер (или плагин/прослойка) отдаёт готовый HTML;
- PHP не запускается;
- MySQL не участвует.
Поэтому страничный кэш почти всегда даёт самый заметный прирост по TTFB и выдерживаемому RPS.
Почему full page cache иногда «ломает» сайт
Основная боль — персонализация и сессии. WordPress и плагины (особенно e-commerce) добавляют динамику: корзина, избранное, цены по ролям, геотаргетинг, сообщения «вы вошли». Если отдать гостю кэшированную страницу не для него — получаем некорректное поведение.
Типовые источники персонализации:
- cookies (авторизация, корзина, валюты/языки, A/B);
- query string (utm-метки, фильтры);
- заголовки вроде
Accept-Language(реже).
Рабочая стратегия почти всегда такая: агрессивно кэшируем гостевой трафик, а для авторизованных упираемся в object cache и оптимизацию PHP/MySQL.
Если вы делаете full page cache на уровне Nginx, обратите внимание на механику «разрешённых» параметров и ключей кэша: ошибка в ключе (например, кэшировать разные utm_* как разные страницы) легко превращает кэш в «раздуватель» диска без пользы.
Для практичных паттернов с map и нормализацией ключа пригодится: Nginx map для управления кэшем и вариативностью ответа.
WP-Cron и кэш: почему фоновые задачи внезапно становятся нагрузкой
wp-cron.php — это псевдо‑крон. По умолчанию он запускается «на посещениях»: пришёл пользователь — WordPress проверил, не пора ли выполнять задачи. На большом трафике это даёт лишние обращения к PHP и БД, а при проблемах с блокировками может превращаться в самоподдерживающуюся нагрузку.
Связь с кэшем такая:
- при нестабильном кэше или постоянной очистке (purge) WP чаще «пересобирает» данные;
- при stampede много запросов одновременно прогревают одни и те же ключи, а wp-cron добавляет фоновые операции;
- некоторые плагины ставят слишком частые cron-задачи, которые неочевидно завязаны на кеш‑ключи и транзиенты.
На проектах, где важна предсказуемость,
wp-cronлучше отделять от пользовательского трафика и запускать системным планировщиком по расписанию.
Базовая схема: отключаете WP-Cron «на хитах», а дальше дергаете его по расписанию из cron.
wp config set DISABLE_WP_CRON true --type=constant
crontab -e
*/5 * * * * /usr/bin/php /var/www/site/public/wp-cron.php >/dev/null 2>&1
Замените путь до PHP и каталога сайта на свои. Если у вас несколько сайтов на одном сервере, разнесите расписание по минутам (например, один сайт на 1,6,11… минуте), чтобы не создавать синхронные пики.
admin-ajax и кэш: почему он опасен для производительности
admin-ajax.php — универсальная точка входа для AJAX в WordPress. Её любят темы, конструкторы, плагины статистики, фильтры каталога, бесконечные ленты и даже формы. И часто она вызывается на каждой странице.
Проблемы:
- запросы к
admin-ajax.phpпочти всегда обходят full page cache; - многие обработчики запускают тяжёлые запросы к БД;
- часто нет защиты от частоты вызова (особенно для гостей).
Что делать практически:
- проверить в браузере (Network), сколько AJAX-вызовов на страницу и какие самые «дорогие»;
- включить логирование медленных запросов на уровне PHP/MySQL и сопоставить с endpoint;
- по возможности переносить публичные AJAX-ручки на REST API с нормальным кэшированием/ETag (если плагин/тема позволяет);
- вынести «необязательные» виджеты (просмотры, популярное, рекомендации) в отложенную загрузку или кэшировать их отдельно.
Отдельный практический маркер: если «главная страница в кэше» летает, а CPU всё равно стабильно высокий, очень часто виноваты именно фоновые AJAX-запросы (и/или heartbeat), которые не видны на уровне page cache.

Cache stampede: как WordPress «умирает» при истечении TTL
Cache stampede — это когда у популярной страницы или ключа истёк TTL, и десятки или сотни запросов одновременно пытаются пересчитать одно и то же. В WordPress это проявляется как внезапные пики CPU/DB, хотя «кэш же включён».
Типовые триггеры:
- одинаковый TTL у большого числа ключей (все истекают в одну секунду);
- purge всего кэша после публикации записи или обновления товара;
- нет «блокировки» на пересчёт (locking) или механизма serve stale;
- кэш прогревается реальными пользователями.
Что работает на практике:
- джиттер TTL — разброс времени жизни ключей (например, 600–900 секунд вместо ровно 600);
- stale-while-revalidate на уровне full page cache: отдаём слегка устаревшее, пока один запрос обновляет;
- locking на пересборку страницы или ключа;
- частичный purge: очищаем только связанные URL/шаблоны, а не весь сайт;
- прогрев (warmup) контролируемым воркером после очистки, а не пользователями.
Практический план: как собрать кэш-стек для WordPress
Ниже — «скелет» стратегии, которая обычно даёт предсказуемый результат на продакшене.
Шаг 1. Определите профиль трафика
- Контентный сайт: гости, мало персонализации → приоритет full page cache.
- WooCommerce/кабинеты: много логинов → приоритет object cache + оптимизация БД, а page cache аккуратно и выборочно.
Шаг 2. Включите персистентный object cache и проверьте размер
Если вы включили Redis или Memcached и «ничего не изменилось», проверьте базовые вещи:
- попадает ли WordPress в персистентный кэш (в админке плагина обычно есть статус);
- нет ли постоянных промахов (miss) из‑за слишком маленькой памяти и агрессивного вытеснения;
- нет ли key prefix конфликтов, если в одном Redis несколько сайтов;
- не храните ли вы в object cache «вечные» данные без TTL (они выдавят всё остальное).
Шаг 3. Настройте full page cache с понятными исключениями
Минимальный набор исключений, который почти всегда нужен:
- не кэшировать страницы для авторизованных пользователей;
- не кэшировать корзину, оформление заказа и аккаунт в e-commerce;
- обходить кэш для запросов с определёнными cookies (корзина, язык, валюта);
- аккуратно обращаться с параметрами в URL: кэшировать только «безопасные» query string.
Отдельно проверьте, что статика (CSS, JS, шрифты) отдается с корректными заголовками кеширования и сжатия. Даже идеальный page cache не спасает, если браузеру на каждом заходе приходится перекачивать одно и то же.
Шаг 4. Разберитесь с wp-cron и admin-ajax
Дальше обычно идут самые «денежные» оптимизации — не про сам кэш, а про то, что кэш обходят:
wp-cron.php: сделать выполнение регулярным и управляемым, убрать чрезмерно частые события.admin-ajax.php: снизить количество вызовов, оптимизировать самые тяжёлые обработчики, кэшировать результаты там, где это безопасно.
Диагностика: как понять, что кэш работает, а не «для галочки»
Когда вы делаете изменения, важно подтверждать эффект цифрами, иначе легко оптимизировать «ощущения».
- TTFB: сравните «без кэша», «после прогрева» и «в момент purge».
- Hit/Miss: смотрите заголовки и статистику уровня page cache и object cache.
- Нагрузка на БД: количество запросов, время, блокировки.
- Пики: что происходит в моменты истечения TTL или после очистки (признаки stampede).
Для WordPress полезно держать отдельный чек‑лист: «что должно кэшироваться» и «что точно не должно кэшироваться», и проверять это после обновлений темы и плагинов.
Частые ошибки и как их избежать
- Очищать весь кэш при любом чихе. Это почти гарантированный путь к stampede.
- Кэшировать то, что зависит от пользователя. Начинайте с гостевого трафика, добавляйте исключения по cookies.
- Ставить все плагины кэша сразу. Конфликт уровней и двойные правила purge — классика.
- Игнорировать admin-ajax. Сайт может быть «закэширован», но AJAX будет съедать 80% CPU.
- Не контролировать размер object cache. Недостаток памяти превращает кэш в генератор лишней работы (постоянные вытеснения).
Итоги: как мыслить про WordPress cache
Если нужно запомнить одну идею: full page cache уменьшает количество запусков WordPress, а object cache уменьшает стоимость каждого запуска. На «контентниках» страничный кэш даёт максимальный эффект, а на магазинах и кабинетах без object cache тяжело держать стабильный отклик.
Отдельно держите в голове «обходные тропы» — wp-cron.php и admin-ajax.php. Именно они часто объясняют, почему включённый кэш не превращается в реальную экономию ресурсов.
И наконец, закладывайте защиту от cache stampede: джиттер TTL, блокировки на пересборку, отдачу stale, контролируемый прогрев. Это делает ускорение не только быстрым, но и надёжным.
Если проект уже перерос «из коробки» возможности общего сервера, часто проще начать с предсказуемой базы: быстрый PHP, отдельная память под Redis и нормальная дисковая подсистема. Для небольших сайтов обычно достаточно виртуального хостинга, а для магазинов и высоких нагрузок лучше сразу планировать переезд на VDS.


