Кратко: транзиенты в WordPress — это встроенный механизм временного кеша: вы кладёте данные под ключом и указываете срок жизни, а WordPress сам удаляет запись, когда срок истёк. Три функции — set_transient(), get_transient() и delete_transient() — закрывают 90 % задач: кеширование тяжёлых запросов, ответов внешних API, результатов расчётов. Главные правила: всегда проверять результат на false, задавать осмысленный TTL, сбрасывать кеш при изменении данных и не хранить в транзиентах большие массивы и персональные данные. Ниже — устройство, рабочие примеры кода, ловушки и чек-лист.
Что такое транзиенты и зачем они нужны
Транзиент — это временная запись в базе (или в object cache), которая живёт заданное время. Механика простая: вы вычисляете результат — например, список популярных товаров или ответ внешнего сервиса — и сохраняете его под ключом на час. Следующие запросы получают готовое значение, а не пересчитывают всё заново.
Зачем это нужно на практике: тяжёлые запросы к базе выполняются на каждой загрузке страницы, а внешние API отвечают по 300–800 мс. Кеш на 15–60 минут снимает нагрузку с базы и ускоряет сайт без изменения логики. Транзиенты — самый дешёвый способ это сделать: они уже есть в ядре, не требуют плагинов и работают с любым кешем объектов, если он подключён.
Важно понимать, что транзиенты — не «вечный кеш». Это именно временное хранилище с автоматическим истечением, и его поведение зависит от того, есть ли на сайте постоянный object cache (Redis, Memcached).
Как устроены транзиенты
У транзиента три параметра: ключ (уникальная строка), значение (любая сериализуемая структура — строка, число, массив, объект) и срок жизни в секундах. Без object cache транзиенты хранятся в таблице wp_options двумя записями: _transient_<ключ> со значением и _transient_timeout_<ключ> со временем истечения.
С включённым постоянным object cache (Redis) та же запись уходит в память, а в базе остаётся только fallback. Это меняет поведение: кеш переживает перезагрузку страниц, но не обязательно переживает перезапуск Redis. Поэтому логика не должна полагаться на то, что значение «точно есть» — только на проверку и повторный расчёт.
| Способ кеширования | Что кеширует | Где живёт | Когда подходит |
|---|---|---|---|
| Транзиенты | Произвольные данные и результаты запросов | wp_options или object cache | Тяжёлые выборки, ответы API, расчёты с TTL |
| Постоянный object cache | Объекты WP_Query, термины, опции | Redis / Memcached | Высокая нагрузка, много запросов на страницу |
| Файловый / страничный кеш | Готовый HTML страницы | Файлы или CDN | Анонимные посетители, статичные страницы |
| Плагины кеша | HTML, CSS/JS, минификация | Файлы, диск | Общее ускорение без правок кода |
Базовый паттерн: set, get, delete
Рабочая схема всегда одна: проверить кеш, при промахе посчитать и сохранить, при изменении данных — удалить. Ниже минимальный пример для тяжёлой выборки.
$key = 'mytheme_top_posts';
$cached = get_transient( $key );
if ( false === $cached ) {
$query = new WP_Query( array(
'posts_per_page' => 10,
'meta_key' => 'views',
'orderby' => 'meta_value_num',
) );
$cached = $query->posts;
set_transient( $key, $cached, HOUR_IN_SECONDS );
}
foreach ( $cached as $post ) {
// вывод
} Ключевые моменты: проверка именно на false (а не на пустоту), ключ с префиксом темы или плагина, TTL константой (HOUR_IN_SECONDS, DAY_IN_SECONDS), чтобы не плодить «магические» числа. И самое частое: после публикации или обновления записи кеш нужно сбросить, иначе посетители увидят старые данные.
Сброс вешают на хуки сохранения — в этом помогают стандартные события WordPress, о которых подробно написано в статье хуки WordPress: actions и filters для новичка. Ещё полезно держать код в дочерней теме, а не в родительской, чтобы обновления темы ничего не сломали: дочерняя тема WordPress: как создать и зачем нужна.
Что кешировать и на сколько
Срок жизни — компромисс между свежестью данных и нагрузкой. Слишком короткий TTL не даёт эффекта, слишком длинный — показывает устаревшее. Ориентиры ниже проверены на реальных проектах.
| Данные | Разумный TTL | Когда сбрасывать |
|---|---|---|
| Список популярных записей | 15–60 минут | По расписанию или при публикации |
| Ответ внешнего API (курсы, погода) | 1–6 часов | Форс-обновление при ошибке |
| Тяжёлый отчёт, агрегаты статистики | 12–24 часа | После импорта или пересчёта |
| Каталог, фасеты фильтров | 30–120 минут | При изменении товаров |
| Меню, справочники, настройки | до недели | При сохранении настроек |
Ориентируйтесь на скорость изменения данных, а не на «чем дольше, тем лучше». Если данные обновляются раз в сутки, часовой TTL ничего не даёт, а суточный — нормален. Если это биржевые курсы, разумны минуты.
Кеширование ответов внешних API
Внешние сервисы — главный источник медленных страниц: один запрос может занимать секунду и больше. Транзиент на час снимает эту задержку и защищает от лимитов. Обязательно обрабатывайте ошибку: если API вернул ошибку, не кешируйте пустоту на час — лучше короткий TTL и повтор.
$key = 'mytheme_currency_rates';
$rates = get_transient( $key );
if ( false === $rates ) {
$response = wp_remote_get( 'https://api.example.com/rates', array(
'timeout' => 5,
) );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
$rates = array();
set_transient( $key, $rates, 5 * MINUTE_IN_SECONDS );
} else {
$rates = json_decode( wp_remote_retrieve_body( $response ), true );
set_transient( $key, $rates, HOUR_IN_SECONDS );
}
} Такой паттерн защищает от «шторма» запросов при недоступном API: сайт показывает последние известные или пустые данные, а не зависает. Если данные критичны, добавьте отдельный флаг ошибки и уведомление администратору — но не блокируйте страницу ожиданием ответа.
Ловушки, о которых узнают на проде
Первая и самая частая: проверка на пустоту вместо false. Функция возвращает false при промахе, но ваши данные тоже могут быть пустым массивом — и тогда кеш будет пересчитываться каждый раз. Проверяйте строго: if ( false === $cached ).
Вторая: хранение больших массивов. Транзиент с тысячей объектов раздувает wp_options и замедляет автозагрузку, если запись попала в autoload. Для больших объёмов лучше объектный кеш или отдельная таблица.
Третья: TTL без инвалидации. Кеш «на час» нормален, но если админ изменил товар, а кеш живёт ещё 40 минут, вы получите баг-репорт. Сбрасывайте кеш на событиях сохранения и публикации. Четвёртая: транзиенты в мультисайте и в CLI-контексте ведут себя по-разному — проверяйте на реальном окружении.
Пятая: забытый префикс в ключе. Два плагина с ключом top_posts затирают друг друга. И шестая: кеширование персональных данных — get_transient() общий для всех, поэтому корзина или данные пользователя в транзиенте утекут другому посетителю. Персональные данные в транзиентах не хранят.
Когда транзиенты — плохой выбор
Есть задачи, где транзиенты вредны. Например, хранение денежных остатков, которые должны быть точными в момент продажи: кеш на час приведёт к продаже отсутствующего товара. Не подходят они и для данных, которые обязаны быть консистентными между запросами (счётчики, блокировки, очереди) — для этого нужны транзакции и отдельные таблицы.
Плохой выбор — и кеширование того, что уже кешируется ядром: WP_Query с постоянным object cache, термины, опции. Двойной кеш только усложняет инвалидацию. И совсем не стоит класть в транзиенты большие бинарные данные и HTML целых страниц: для этого есть страничный кеш и CDN.
Отдельно про тяжёлые SQL-запросы: если выборка медленная, сначала проверьте индексы и сам запрос — примеры безопасной работы с базой есть в статье $wpdb в WordPress: безопасные запросы. Транзиент ускоряет повторные вызовы, но не лечит плохой запрос.
Типичные ошибки
Ошибки почти всегда одни и те же, и все они дешёво ловятся на ревью. Ниже — короткий список для самопроверки.
| Ошибка | Последствие | Как правильно |
|---|---|---|
| Проверка на пустоту вместо false | Кеш не работает, нагрузка как без него | Строгое сравнение с false |
| Большой массив в транзиенте | Раздувание wp_options, медленная автозагрузка | Object cache или своя таблица |
| Нет инвалидации | Устаревшие данные после правок | delete_transient на save_post |
| Кеш ошибок API надолго | Сайт часами показывает пустоту | Короткий TTL при ошибке, повтор |
| Ключ без префикса | Конфликт с другими плагинами | Префикс темы или плагина |
| Персональные данные в кеше | Утечка между посетителями | Кешировать только общие данные |
Отладка простая: включите WP_DEBUG, посмотрите, какие ключи создаются, и проверьте, не растёт ли таблица опций. Если транзиентов стало слишком много, поможет очистка по расписанию — как устроен планировщик, разобрано в статье WP-Cron: планировщик задач WordPress.
Чек-лист внедрения
1. Определите, что именно тормозит: запрос, API или расчёт. 2. Выберите TTL по скорости изменения данных. 3. Оберните вычисление в get/set с проверкой на false. 4. Добавьте префикс в ключ. 5. Повесьте сброс кеша на события сохранения и публикации. 6. Обработайте ошибки внешнего API коротким TTL. 7. Не храните персональные данные и большие массивы. 8. Проверьте поведение с включённым и выключенным object cache. 9. Убедитесь, что кеш не мешает админке и редактору. 10. Замерьте время ответа до и после — эффект должен быть виден в цифрах.
Для замеров достаточно записать время генерации страницы в лог и сравнить до и после. Если выигрыша нет, значит кеш стоит не там, где надо, или TTL слишком короткий.

Частые вопросы про транзиенты WordPress
Чем транзиенты отличаются от object cache?
Транзиенты — это API для временного хранения произвольных данных с TTL. Object cache — слой кеширования объектов WordPress (запросов, терминов, опций). Если постоянный object cache включён, транзиенты автоматически хранятся в нём, а не в базе. То есть транзиенты — ваш инструмент, object cache — инфраструктура под ними.
Что вернёт get_transient, если записи нет или срок истёк?
Функция вернёт false. Поэтому проверять результат нужно строго через if ( false === $cached ), а не через пустоту: пустой массив — это тоже валидные данные, и при нестрогой проверке кеш будет пересчитываться на каждом запросе.
Какой TTL выбрать для кеша запросов?
Зависит от скорости изменения данных: популярные записи — 15–60 минут, ответы внешних API — 1–6 часов, агрегаты и отчёты — 12–24 часа. Общее правило: TTL не длиннее, чем допустимая для вас задержка обновления. Если данные меняются сразу и кеш недопустим — кешировать не нужно.
Как сбросить транзиент при публикации записи?
Повесить удаление на хуки save_post и deleted_post: внутри хука вызывать delete_transient с теми же ключами, что использует вывод. Если ключей много, используйте общий префикс и удаляйте группу по списку. Это дешевле, чем ждать истечения TTL, и снимает жалобы «на сайте старые данные».
Можно ли хранить в транзиентах большие массивы?
Нежелательно. Крупные записи раздувают wp_options и замедляют автозагрузку, а с object cache занимают память Redis. Для больших объёмов лучше отдельная таблица или кеширование частями. Ориентир: если данные больше десятков килобайт, транзиент — не лучшее место.
Видны ли транзиенты посетителям сайта и безопасны ли они?
Сама запись не видна в браузере, но get_transient общий для всех посетителей: что положили — то получат все. Поэтому в транзиентах нельзя хранить персональные данные, корзины и токены. Кешируйте только общие данные: списки записей, справочники, ответы API.
Вывод
Транзиенты — простой и мощный инструмент, если использовать их по назначению: временный кеш вычислений, тяжёлых запросов и внешних API. Три функции, строгая проверка на false, осмысленный TTL и сброс на событиях — этого достаточно для большинства задач.
Главное — не превращать кеш в свалку: не хранить большие массивы и персональные данные, не кешировать ошибки надолго и всегда иметь план инвалидации. Тогда сайт будет быстрее, а данные — актуальными.
Если нужна доработка кеширования, оптимизация запросов или ускорение сайта — эту задачу можно передать одной команде. Мы находим узкие места, настраиваем object cache и транзиенты, чистим раздутые опции и проверяем результат замерами. Посмотрите услуги разработки и поддержки сайтов, изучите портфолио проектов и почитайте блог о WordPress. Опишите задачу через форму контактов — предложим решение и рассчитаем стоимость.



