+7 938 150-78-77

Сервер для интернет-магазина: что реально влияет на скорость под нагрузкой

Картинки сжаты, скрипты отложены, а каталог всё равно думает секунду. Разбираем серверную часть: от расчёта числа процессов PHP до буферного пула базы и кеша на уровне nginx.

М Матвей Калашников Основатель студии 09 ноября 2026 14 минут чтения
Сервер для интернет-магазина: что реально влияет на скорость под нагрузкой

Про фронтенд написано много: сжать картинки, отложить скрипты, собрать критический CSS. Но у магазина с настоящим каталогом половина проблем живёт не в браузере, а на сервере — и ни одна оптимизация разметки её не лечит. Разберём серверную часть по порядку: что мерить, что настраивать и в каком порядке, чтобы ускорение сайта не превратилось в перебор настроек наугад.

Где именно теряется время

Между нажатием ссылки и появлением страницы происходит несколько этапов, и каждый из них измеряется отдельно. Сваливать их в одно слово «медленно» — главная причина, по которой оптимизация не даёт результата: чинят не то, что тормозит.

  • Соединение: DNS, установка TCP, рукопожатие TLS — десятки миллисекунд, лечится настройкой один раз
  • Ожидание ответа сервера: сюда входит вся работа PHP и базы — именно здесь у каталогов уходят секунды
  • Передача документа: зависит от размера HTML и сжатия
  • Отрисовка в браузере: блокирующие стили и скрипты, шрифты, изображения
  • Дозагрузка данных после отрисовки: корзина, цены, рекомендации, которые подтягиваются запросами

Фронтенд отвечает за четвёртый и пятый пункты, сервер — за второй. Если ожидание ответа 1200 миллисекунд, то любая работа с картинками и скриптами будет улучшать картину на сотые доли: человек всё равно смотрит в пустой экран, пока сервер думает.

TTFB: первое, что надо измерить

Время до первого байта показывает, сколько сервер думал над страницей. Мерить его надо не в браузере с открытой консолью и включёнными расширениями, а запросом из командной строки, несколько раз, с разных страниц.

  • Главная, категория с фильтром, карточка товара, страница корзины — у них принципиально разная цена в ресурсах
  • Первый запрос после сброса кеша и второй подряд — разница показывает, работает ли кеширование вообще
  • Авторизованный посетитель и анонимный: для первого кеш страниц почти всегда отключён, и именно он видит настоящую скорость сайта
  • Ответ из локальной сети сервера против ответа снаружи — отделяет работу приложения от сетевых задержек
  • Запрос в пиковые часы и ночью: деградация под нагрузкой — отдельный диагноз, и настраивается она иначе

Ориентир простой: для страницы, отдающейся из кеша, ожидание ответа измеряется десятками миллисекунд. Для динамической страницы каталога приемлемо до трёхсот. Если видите секунду и больше — дело не в настройках, а в количестве запросов к базе на одну страницу, и начинать надо с профилирования, а не с тюнинга.

Настройка сервера не ускоряет плохой код, она только перестаёт его замедлять. Триста запросов к базе на отрисовку категории останутся тремястами запросами на любом железе — просто на дорогом они будут выполняться чуть быстрее.

Хостинг, VPS или выделенный сервер

Признак для выбора один — нужен ли вам контроль над настройками. На виртуальном хостинге вы получаете готовую среду, в которой нельзя поменять версию PHP под себя, поднять кеш в памяти, настроить параметры базы или посмотреть, что происходит с диском.

  • Виртуальный хостинг подходит для лендинга, визитки, небольшого корпоративного сайта с десятками страниц
  • Магазину с каталогом нужен сервер с корневым доступом: без него половина пунктов этой статьи недоступна технически
  • Соседи по хостингу влияют на скорость, и это невозможно ни измерить, ни исправить со своей стороны
  • Выделенный сервер нужен не раньше, чем виртуальный упирается в ресурсы на реальном трафике — а не на всякий случай
  • Географически сервер должен стоять там, где покупатели: для российской аудитории это Россия, и причина не только в скорости, но и в требованиях к хранению персональных данных

Отдельно про перенос базы на отдельный сервер. Это правильный шаг для крупного проекта, но на старте он часто делает хуже: вместо обращения к базе на том же хосте появляется сетевой round-trip, и страница с тремя сотнями запросов начинает работать медленнее, чем была.

Память важнее ядер

При выборе конфигурации обычно смотрят на процессор. Для магазина критичнее память: от неё зависит, сколько одновременных запросов сервер способен обработать и сколько данных база держит в оперативке вместо чтения с диска.

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

  • Подкачка не решает нехватку памяти, а превращает её в деградацию: лучше честный отказ в соединении, чем тридцатисекундные ответы
  • Если в журнале ядра встречается убийца процессов по нехватке памяти, никакие другие настройки обсуждать смысла нет
  • Сборка проекта, выгрузки и обмен с учётной системой едят память в те же моменты, что и посетители — это надо учитывать в расчёте
  • Фоновые задачи стоит выносить в отдельный пул процессов, чтобы они не отнимали рабочие процессы у посетителей

PHP-FPM: количество процессов

Главный параметр — максимальное число дочерних процессов. Считается он не по вкусу, а делением доступной под PHP памяти на средний объём одного процесса. Средний объём смотрится на работающем сервере, а не берётся из статьи в интернете: у магазина на тяжёлой платформе процесс занимает в разы больше, чем у простого сайта.

  • Слишком маленькое значение — запросы встают в очередь, и под нагрузкой ожидание ответа растёт, хотя процессор свободен
  • Слишком большое — память заканчивается, сервер уходит в подкачку, отваливается всё сразу
  • Режим статического пула предсказуемее динамического: процессы создаются сразу и не тратят время на запуск под нагрузкой
  • Ограничение числа запросов на процесс защищает от медленных утечек памяти в коде и расширениях
  • Соединение через unix-сокет, а не через TCP, экономит немного на каждом запросе
  • Журнал медленных запросов PHP с порогом в несколько секунд — самый дешёвый способ увидеть, где именно код зависает: в журнал пишется стек вызовов

Отдельно стоит включить страницу состояния пула. Она показывает, сколько процессов занято прямо сейчас и какая была максимальная очередь, — без этого настройка пула превращается в угадывание.

OPcache и версия PHP

Самое дешёвое ускорение, которое до сих пор встречается ненастроенным. OPcache хранит скомпилированный байт-код в памяти, чтобы не разбирать исходники на каждом запросе. Включён он почти всегда, но объёма памяти и лимита числа файлов по умолчанию крупному проекту не хватает — а при переполнении кеш просто перестаёт работать, молча.

  • Число кешируемых файлов должно быть больше, чем файлов в проекте: у тяжёлых платформ это десятки тысяч, и значение по умолчанию мало
  • Объём памяти под кеш стоит задавать с запасом и следить за процентом заполнения и числом вытеснений
  • Проверку времени изменения файлов на боевом сервере отключают — но тогда после каждого обновления кода нужен перезапуск пула, иначе сайт продолжит работать по старому коду
  • Кеш путей файловой системы тоже имеет лимит, и у проектов с глубокой структурой каталогов его стоит поднять
  • Обновление версии PHP на одну мажорную даёт прирост, сопоставимый с любой ручной оптимизацией, — и обычно требует лишь проверки совместимости модулей

База: буферный пул и медленные запросы

Для каталога база — главный источник задержки. И здесь всего два действия дают почти весь результат.

Первое: буферный пул должен вмещать рабочий набор данных. Если он меньше размера активных таблиц и индексов, база читает с диска при каждом обращении, и дальше всё зависит от скорости диска, а не от скорости базы. На сервере, где кроме базы ничего нет, под пул отдают большую часть памяти; на общем сервере — считают остаток после PHP.

Второе: включить журнал медленных запросов с низким порогом и посмотреть, что в него попадает. Как правило, оказывается, что восемьдесят процентов времени съедают три-четыре однотипных запроса без подходящего индекса — и добавление индекса даёт кратное ускорение категории.

  • Запросы без использования индексов стоит логировать отдельно: это готовый список задач
  • Разбор плана выполнения показывает, сколько строк база перебирает фактически, — это объективнее, чем время, которое зависит от нагрузки
  • Кеш запросов в современных версиях MySQL отсутствует: настройки из старых инструкций либо игнорируются, либо не дают серверу запуститься
  • Фильтрация по нескольким свойствам в фасетной навигации — самый тяжёлый тип запроса в магазине, и решается он чаще структурой таблиц, а не настройкой сервера
  • Таблицы в старом формате хранения без поддержки блокировок на уровне строки под нагрузкой превращаются в очередь: формат надо проверить и перевести

Отдельная статья расходов — временные таблицы на диске. Если лимиты для них малы, тяжёлые выборки с сортировкой начинают писать на диск, и это видно по счётчикам базы. Поднятие лимитов помогает, но корень обычно в самом запросе.

Кеш в памяти: сессии и объекты

Два слоя, которые часто путают. Кеш страниц отдаёт готовый HTML и не работает для авторизованных и для корзины. Объектный кеш хранит результаты отдельных вычислений и запросов — он работает всегда, в том числе для авторизованных, и именно он спасает каталог.

  • Объектный кеш в памяти вместо файлов на диске — заметный выигрыш на каталоге с большим числом мелких обращений
  • Сессии в памяти вместо файлов убирают блокировки файла сессии: без этого параллельные запросы одного посетителя выстраиваются в очередь
  • Кеш и сессии лучше держать в разных базах хранилища: сброс кеша не должен разлогинивать людей
  • У хранилища в памяти должен быть лимит и политика вытеснения, иначе оно съест память, рассчитанную под PHP
  • Инвалидация важнее самого кеша: после обмена с учётной системой кеш каталога обязан сбрасываться, иначе цены на витрине будут вчерашними

Почему установка готового плагина кеширования сама по себе не ускоряет магазин, мы разбирали подробно: причина ровно в этом разделении слоёв.

Кеш на уровне веб-сервера

Самый быстрый ответ — тот, который отдаётся до запуска PHP. Веб-сервер умеет кешировать ответы сам, и для анонимных посетителей это сокращает ожидание до единиц миллисекунд. Но включать такой кеш без условий на магазине нельзя — иначе один посетитель увидит корзину другого.

  • Обход кеша по признаку авторизации и по наличию непустой корзины — обязательное условие, и проверять его надо до включения кеша на боевом сайте
  • Методы, отличные от GET, не кешируются никогда
  • Короткое время жизни кеша даже на уровне секунд уже снимает пик с главной и категорий при всплеске трафика
  • Выдача устаревшего ответа при ошибке приложения спасает сайт от белого экрана в момент сбоя
  • Сжатие ответа, протокол второй версии, повторное использование соединений, кеширование открытых файловых дескрипторов — настраивается один раз и работает всегда
  • Статика должна отдаваться веб-сервером напрямую с длинным временем жизни кеша и версионированием в имени файла

Диск: важна не ёмкость

Для базы данных значение имеет число операций ввода-вывода в секунду и задержка отдельной операции, а не объём. Разница между механическим диском, SSD по старому интерфейсу и современным накопителем для базы кратная — и ощущается именно тогда, когда данные не поместились в память.

Признак, что проблема в диске: при нормальной загрузке процессора растёт время ожидания ввода-вывода, а запросы к базе замедляются все разом, независимо от типа. Смотрится это стандартными средствами наблюдения за системой, и перепутать это ни с чем нельзя.

Чем мерить, чтобы не угадывать

  • Журнал медленных запросов базы — главный источник конкретных задач
  • Журнал медленных запросов PHP со стеком вызовов — показывает место в коде, а не симптом
  • Состояние пула процессов: занятые процессы, длина очереди, максимумы за сутки
  • Статистика OPcache: заполнение, вытеснения, процент попаданий
  • Системные счётчики: загрузка процессора, свободная память, ожидание диска, подкачка
  • Нагрузочная проверка на копии сайта, а не на боевом: она отвечает на вопрос, сколько одновременных посетителей сервер держит до деградации
  • Журнал доступа веб-сервера с временем обработки каждого запроса — покажет самые дорогие адреса на реальном трафике

Последний пункт недооценивают. Добавить время обработки в формат журнала — пять минут работы, после чего видно, что половину ресурсов съедает не каталог, а, например, поиск по сайту или страница, которую обходит робот.

Порядок работ

  • Снять базовые показатели: ожидание ответа на пяти типах страниц, для анонимного и авторизованного
  • Проверить память: хватает ли её при текущих лимитах, нет ли подкачки
  • Включить журналы медленных запросов базы и PHP, собрать данные за сутки
  • Исправить то, что в них нашлось: индексы, лишние запросы в цикле, тяжёлые выборки
  • Настроить OPcache и обновить версию PHP, если она старая
  • Рассчитать и выставить число процессов PHP под реальный объём памяти
  • Подобрать буферный пул базы под размер рабочего набора данных
  • Перевести сессии и объектный кеш в память, настроить сброс кеша после обмена
  • Включить кеш веб-сервера с корректными условиями обхода
  • Повторить замеры и зафиксировать результат — иначе непонятно, что из этого сработало

Порядок важен: настройка кеша до исправления запросов прячет проблему, а не решает её. Первый же сброс кеша или заход робота по неоткешированным адресам возвращает сайт в исходное состояние, и выяснять причину приходится заново.

Мы занимаемся этим в таком порядке: сначала замеры и журналы, потом исправления, потом настройка, снова замеры. Разовая работа по серверной части — это ускорение сайта, постоянное наблюдение за ресурсами, обновлениями и резервными копиями — администрирование сервера. Если тормозит магазин на готовой платформе с набором расширений, начинать стоит с разбора того, что именно выполняется на каждой странице, — это входит в поддержку. Фронтенд-часть и показатели, которые видит поисковик, мы разбирали в статье про Core Web Vitals.

М Матвей Калашников · основатель Sapphireweb 6 лет делает сайты и интеграции на 1С-Битрикс и WordPress. Пишет о том, что чинит своими руками. Статья опубликована 09 ноября 2026. Пересматриваем материалы раз в квартал и правим то, что устарело.
Вопросы

Отвечаем
заранее

Не нашли свой вопрос? Напишите в Telegram — ответим без долгих согласований.

Число процессов PHP-FPM под доступную память, версия PHP с OPcache, буферный пул базы и кеш на уровне веб-сервера. Ядра важны меньше, чем память.
С измерения TTFB на реальных страницах каталога и поиска медленных запросов в базе. Без цифр настройка превращается в угадывание.
Хостинга хватает витрине, магазину с обменом нужен VPS с контролем над PHP и базой. Выделенный сервер оправдан на больших каталогах и постоянной нагрузке.

Расскажите
о задаче

Пришлите ссылку на сайт и опишите задачу. Уточним исходные данные, предложим состав работ и подготовим оценку стоимости и сроков. Пришлите сайт и задачу — подготовим оценку работ, стоимости и сроков.

Вопрос по статье: Сервер для интернет-магазина: что реально влияет на скорость под нагрузкой