Нагрузка в MODX: что ломается внутри сайта первым
В MODX узкое место часто появляется не в PHP, а на стыке кеша, базы данных, сниппетов и PHP-FPM. Разбираем путь запроса, признаки перегрузки и замеры, которые показывают реальную причину.

Сайт на MODX может начать отдавать 502, открывать страницы по 5–10 секунд или упираться в 100% CPU задолго до того, как закончится пропускная способность сервера. Причина обычно не одна: кеш перестал помогать, страница собрала десятки запросов к базе, сниппет выполнился без кеширования, а PHP-FPM одновременно обслуживает слишком много тяжёлых запросов. Ниже — модель нагрузки для MODX Revolution 2.8.x и 3.x, без выдуманных цифр: фактические пределы нужно измерять на вашей версии, базе, конфигурации PHP и объёме контента.
Как запрос проходит через MODX
Обычный запрос к странице начинается на веб-сервере и передаётся PHP. MODX загружает контекст, определяет ресурс, проверяет доступность кешированных данных и строит ответ из полей ресурса, чанков, шаблонов, TV-параметров и сниппетов. После этого результат может попасть в кеш, а PHP-процесс освобождается.
На нагрузке важен не сам размер HTML, а число операций до его формирования. Две страницы одинакового размера могут вести себя совершенно по-разному: одна отдаётся из кеша, другая запускает несколько сниппетов, делает выборки по большой таблице и обращается к внешнему API.
Кеш — это сокращение работы, а не ускоритель любой страницы
Если ресурс и его зависимости можно безопасно кешировать, следующий запрос не повторяет всю цепочку вычислений. Но кеш не спасает страницу, если она регулярно инвалидируется, содержит некешируемые участки или каждый раз выполняет персональную логику.
Кеширование также не устраняет стоимость первого запроса после очистки кеша. Если одновременно пришёл всплеск пользователей, несколько PHP-процессов могут начать заново собирать один и тот же результат. Внешне это выглядит как внезапный рост CPU и времени ответа сразу после публикации или очистки кеша.
Что делают чанки, TV и сниппеты
Чанк сам по себе обычно не является проблемой: это фрагмент шаблона. Риск появляется, когда внутри страницы много динамических вызовов. TV-параметры удобны для редактора, но массовая выборка ресурсов с большим числом TV может увеличить объём работы с базой и обработку результата.
Сниппет — полноценный PHP-код. Если он обращается к базе, перебирает большой набор ресурсов, читает файлы или вызывает внешний сервис, его цена складывается с ценой всех остальных сниппетов страницы. Один медленный вызов часто заметнее, чем десятки простых подстановок.
На нагрузке MODX тормозит не «из-за шаблона» вообще, а из-за конкретной цепочки: запрос к ресурсу, выборка данных, выполнение PHP, обращение к внешнему сервису и только потом генерация HTML.
Где появляется узкое место
| Симптом | Вероятный слой | Что проверить |
|---|---|---|
| Медленно только после очистки кеша | Генерация страницы и прогрев кеша | Время первого и повторного запроса, параллельный прогрев |
| Растёт CPU PHP, база почти свободна | Сниппеты, шаблоны, файловые операции | Профилирование PHP и список вызываемых компонентов |
| Растёт время SQL, база занята | Выборки ресурсов, TV, фильтрация и сортировка | Медленные запросы, план выполнения, индексы |
| 502 или очередь запросов PHP-FPM | Исчерпание рабочих процессов или долгие запросы | Логи PHP-FPM и веб-сервера, число активных процессов |
| Всё быстро в админке, но медленно снаружи | Публичная страница или её кеш | Запрос без авторизации, заголовки кеша, повторный запрос |
Сноска: PHP-FPM — менеджер процессов PHP, который держит пул рабочих процессов и передаёт им запросы от веб-сервера. Если все процессы заняты, новые запросы ждут в очереди или получают ошибку.
Как разбирать нагрузку, а не угадывать
Разбор начинается с фиксации условий. Запишите версию MODX, PHP и базы данных, веб-сервер, объём таблиц, включён ли кеш, авторизован ли пользователь и какой URL проверяется. Без этого замеры «до» и «после» нельзя сравнить.
- Разделите холодный и тёплый запрос. Очистите кеш только один раз, измерьте первый ответ, затем повторите тот же запрос несколько раз. Если первый запрос сильно медленнее остальных, проблема связана с генерацией или прогревом, а не обязательно с общей производительностью. Проверка: время ответа стабилизируется после повторных запросов.
- Проверьте страницу без браузерного шума. Сравнивайте один и тот же URL без расширений, параллельных вкладок и авторизации, затем отдельно проверьте авторизованный сценарий. Для динамических страниц результат может отличаться из-за сессии и персонализации. Проверка: для каждого сценария есть отдельный набор замеров.
- Посмотрите логи веб-сервера и PHP-FPM. Ищите 502, тайм-ауты, превышение времени выполнения и сообщения о занятых рабочих процессах. Один код ответа не объясняет причину, но показывает, где запрос перестал проходить цепочку. Проверка: для медленного запроса найдены соответствующие записи по времени.
- Проверьте базу отдельно. Сопоставьте время ответа страницы с длительностью SQL-запросов. Для подозрительных выборок изучите план выполнения средствами вашей СУБД, а не добавляйте индексы вслепую. Проверка: вы знаете, какой запрос занимает основное время и почему.
- Отключайте подозрительные участки по одному. В тестовой копии временно уберите один сниппет или тяжёлую выборку и повторите замер. Несколько изменений сразу скрывают вклад каждого компонента. Проверка: после каждого изменения есть сравнимое измерение, а не субъективное ощущение.
Что ломается первым после роста трафика
Пул PHP-FPM
Каждый долгий запрос занимает рабочий процесс дольше. При всплеске трафика новые запросы ждут свободный процесс, а если очередь и тайм-ауты исчерпаны, пользователь видит 502 или 504. Увеличить число процессов можно не всегда: каждый процесс потребляет память, поэтому настройка должна учитывать доступную RAM и размер процесса.
Смотрите не только на среднее время ответа. Важны максимальные значения, доля ошибок, число активных процессов и время ожидания в очереди. Среднее значение может выглядеть приемлемо, пока часть пользователей уже получает тайм-ауты.
База данных
MODX хранит ресурсы, элементы конфигурации, пользователей и другие сущности в базе. Нагрузка растёт, когда страница запрашивает большие наборы данных, сортирует их без подходящего индекса или повторяет одинаковые выборки для нескольких блоков.
Особенно опасен паттерн «получить список, затем для каждого элемента получить дополнительные данные». На небольшой базе он незаметен, но при росте каталога число запросов увеличивается вместе с количеством элементов. Исправление может потребовать изменить выборку, ограничить поля, добавить пагинацию или вынести подготовку данных из запроса пользователя.
Внешние сервисы
Платёжный шлюз, CRM, карта, поисковый сервис или HTTP-запрос из сниппета добавляют в страницу чужое время ответа. Если вызов выполняется синхронно, пользователь ждёт его вместе с HTML. Если внешний сервис недоступен, ваш сайт может зависать до тайм-аута.
Для публичной страницы безопаснее заранее получать данные по расписанию и хранить результат локально. Тайм-аут, повторные попытки и резервное поведение должны быть определены отдельно. Инвалидация кеша — отдельная тема; здесь важен сам факт, что внешний вызов нельзя считать бесплатным.
Граничные случаи
Кешированная публичная страница и личный кабинет — разные профили нагрузки. В первом случае основная работа может происходить во время очистки кеша, во втором почти каждый запрос обязан выполнить персональную логику.
Публикация большого числа ресурсов также создаёт короткий, но резкий пик: меняются зависимости, обновляется кеш, а пользователи продолжают открывать страницы. Если после публикации система «замирает», измеряйте не только обычный трафик, но и сценарий массовой очистки или обновления.
Нельзя переносить результат локального теста на продакшен без оговорок. Отличаться могут размер базы, версия PHP, настройки OPcache, диски, TLS, CDN, фоновые задания и число одновременных пользователей. Если нагрузочного теста нет, честный результат — не прогноз пропускной способности, а список измерений, которые ещё нужно провести.
Что делать дальше
Соберите один воспроизводимый сценарий: конкретный URL, холодный и тёплый кеш, пять или десять последовательных запросов, затем контролируемое число параллельных запросов. Зафиксируйте p50, p95 и p99 времени ответа, долю ошибок, CPU, память, активные процессы PHP-FPM и время SQL-запросов.
После этого исправляйте самый дорогой участок, а не весь сайт сразу. Начните с медленного сниппета или запроса, повторите тот же сценарий и сохраните результат рядом с исходным замером. Для MODX под нагрузкой важнее такая цепочка доказательств, чем универсальное обещание «включить кеш и увеличить сервер».
Инфобез и 152-ФЗ: Аудит политик конфиденциальности, правила сбора cookie.
Спросить за 20 ₽Источники: Официальная документация MODX, Официальный сайт MODX
Частые вопросы
Почему MODX медленный только после очистки кеша?
Поможет ли увеличить число процессов PHP-FPM?
Почему кеш не ускоряет страницу с динамическим сниппетом?
Что делать, если под нагрузкой появляется 502?
Можно ли заранее назвать, сколько одновременных пользователей выдержит MODX?
Нужно ли разбирать нагрузку отдельно для админки и публичной части?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.