Переехали на VPS, а быстрее не стало: разбираем, куда ушёл выигрыш
Вы переехали с shared-хостинга на VPS, ожидая, что выделенные ресурсы дадут заметный прирост скорости — а сайт открывается так же, как раньше, а иногда и медленнее. Формально у вас теперь свои CPU-ядра и своя память, никто больше не делит с вами диск и процессор. Но «формально своё» и «реально быстрее» — разные вещи, и разрыв между ними почти всегда объясняется одной из трёх причин, а чаще всего — их суммой. Разберём, куда именно делся ожидаемый выигрыш и что с этим делать.
Содержание
- Почему VPS не ускоряет автоматически
- Что вы потеряли вместе со shared-хостингом, сами того не заметив
- Дефолтный конфиг VPS — это чистый лист, а не оптимизация
- Как отличить субъективное «медленнее» от реальной проблемы
- Профилирование: где реально уходит время
- Когда дело вообще не в сервере: архитектурная проблема
- Практический план: как реализовать потенциал VPS
Почему VPS не ускоряет автоматически
Первое, что стоит признать: переезд на VPS покупает вам изоляцию и контроль, а не производительность как таковую. На shared-хостинге вы делите физический сервер с десятками, а то и сотнями других аккаунтов — источник реальных проблем: шумные соседи, лимиты на процессы, непредсказуемые квоты на CPU-время. Устранение этого фактора часто ощущается как облегчение, но не всегда как прирост скорости в цифрах.
VPS решает именно проблему изоляции: ресурсы гарантированы (у честного, не переподписанного провайдера) и не зависят от соседей. Но гарантированный 1 vCPU и 1-2 ГБ RAM на начальном тарифе — это часто меньше, чем реально доставалось сайту на shared-хостинге в спокойные часы, когда соседи не создавали нагрузку. Формально скромные ресурсы VPS на практике могут оказаться теми же или даже более узкими, чем то, что неявно доставалось на переполненном, но хорошо забуференном shared-сервере.
Второй и более важный момент: сама производительность на shared-хостинге определялась не только железом, а конфигурацией — которую настраивал провайдер, а не вы, и о существовании которой вы могли даже не подозревать.
Что вы потеряли вместе со shared-хостингом, сами того не заметив
Провайдер shared-хостинга годами тюнингует одну и ту же связку — Apache или nginx, PHP-FPM или mod_php, MySQL или MariaDB — под тысячи однотипных сайтов (чаще всего WordPress, Bitrix, самописные PHP-проекты). Это коммерчески оправдано: чем эффективнее общая конфигурация, тем больше клиентов помещается на одну машину. В результате на shared-хостинге незаметно для вас работали вещи, которые теперь придётся настраивать самим:
- PHP OPcache был включён и прогрет годами с разумными лимитами
opcache.memory_consumption— на свежем VPS модуль часто установлен, но не включён или включён с дефолтами, не рассчитанными на размер проекта. - Пул PHP-FPM был настроен под конкретный тип нагрузки — панель хостинга сама подбирала
pm.max_childrenисходя из выделенной аккаунту памяти. На VPS вы получаете один дефолтный пул на весь сервер, который никто под вашу нагрузку не подбирал. - MySQL/MariaDB на shared-платформе часто вынесена на отдельные серверы с приличным
innodb_buffer_pool_size, настроенным под суммарный объём данных многих клиентов. Маленький сайт неявно выигрывал от того, что база уже была «разогрета» под сотни соседних баз. - HTTP/2, Brotli/gzip, статическая раздача с правильными заголовками кеширования — на панелях вроде cPanel, ISPmanager, Plesk чаще всего включено из коробки, и вы никогда не задумывались, что это нужно настраивать.
- Отдельный слой кеширования (memcached, встроенный page cache панели, LiteSpeed Cache) — многие shared-провайдеры ставят это по умолчанию для CMS-сайтов, экономя себе ресурсы.
Ни один пункт не является следствием «мощного железа» — это следствие конфигурации, накопленной за годы эксплуатации похожей нагрузки. Переехав на VPS, вы не потеряли эти оптимизации явно — вы оказались в системе, где их никто изначально не применил. План самого переезда без простоя разобран здесь — стоит свериться с ним ещё на этапе планирования миграции.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSДефолтный конфиг VPS — это чистый лист, а не оптимизация
Второе заблуждение — что установка веб-сервера и базы данных «по умолчанию» на VPS уже даёт разумный результат. Дефолтные конфиги пакетов из репозитория дистрибутива рассчитаны на минимальное потребление ресурсов и совместимость с любым железом — от 512 МБ RAM до 128 ГБ. Они не рассчитаны на то, чтобы выжать максимум из конкретной машины.
Несколько типичных примеров, которые встречаются почти на каждом свежем VPS:
MySQL/MariaDB. Дефолтный innodb_buffer_pool_size в конфиге многих дистрибутивных сборок — это скромное фиксированное значение (порядка 128 МБ), независимо от того, сколько реально памяти у сервера. Если у VPS 8 ГБ RAM, а буферный пул использует 128 МБ, база постоянно вычитывает данные с диска вместо того, чтобы держать рабочий набор в памяти. Разница в отклике может быть кратной — насколько именно, зависит от объёма данных и паттерна запросов, точную цифру без замера приводить не стоит.
Nginx. worker_processes часто уже стоит auto, но worker_connections в блоке events нередко остаётся на дефолтных 768-1024 — достаточно для теста, но может стать потолком при реальной параллельной нагрузке. keepalive_timeout, буферы proxy_buffer_size/fastcgi_buffers и включение gzip/brotli тоже требуют явной настройки, а не наследуются откуда-то сами.
PHP-FPM. Дефолтный www.conf ставит pm = dynamic со скромными pm.max_children, не соотнесёнными с объёмом памяти сервера и весом одного PHP-процесса приложения. Итог — либо процессов слишком мало (запросы встают в очередь при параллельной нагрузке), либо слишком много (сервер уходит в своп при пиках).
Осознанный, а не дефолтный расчёт pm.max_children — отталкиваться нужно от реального потребления памяти одним воркером, а не от интуиции:
# Смотрим, сколько реально ест один php-fpm воркер под вашей нагрузкой
ps --no-headers -o "rss,cmd" -C php-fpm* | awk '{sum+=$1; count++} END {print sum/count/1024 " MB average"}'
# Дальше: (RAM_доступная_под_php_fpm_в_МБ) / (средний_вес_воркера_в_МБ) = pm.max_children
Дефолты не «плохие» — это разумный компромисс для незнакомой машины. Но компромисс не равен настройке под вашу нагрузку, и разница между ними — это ровно тот выигрыш, который вы ожидали получить от переезда, но не получили автоматически.
Как отличить субъективное «медленнее» от реальной проблемы
Прежде чем что-либо тюнить, стоит заменить ощущение «вроде не быстрее» на конкретные цифры. Субъективная оценка ненадёжна: она зависит от интернета в момент теста, от кеша браузера, от того, тестировали ли вы одну и ту же страницу или разные.
Минимальный набор объективных замеров до и после переезда:
- TTFB (Time to First Byte) — время от отправки запроса до первого байта ответа. Меряется через
curl -wили вкладку Network в браузере. Если TTFB вырос или не изменился при формально более мощном сервере — это прямой сигнал, что узкое место не в сети. Как раскладывать TTFB на сетевую и серверную часть, разобрано в отдельной статье про TTFB 800 мс при пинге 20 мс — стоит прогнать те же замеры на своём проекте.
curl -w "@curl-format.txt" -o /dev/null -s https://ваш-сайт.ru/
- Полное время загрузки страницы — через
curl -w "%{time_total}\n"или инструменты вроде WebPageTest — со стороны реального пользователя, а не только сервера. - Нагрузочное сравнение — не одиночный запрос, а серия. Утилиты
ab(Apache Bench) илиwrkдают распределение времени ответа под параллельной нагрузкой, а не одну точку:
wrk -t4 -c50 -d30s https://ваш-сайт.ru/
- Системные метрики сервера в моменты нагрузки —
htop(загрузка CPU по ядрам, есть ли iowait),vmstat 1(своп, контекстные переключения),iostat -x 1(утилизация диска, задержки чтения/записи). Если во время теста CPU простаивает, а ответ всё равно медленный — узкое место точно не в вычислительных ресурсах.
Важно сравнивать одинаковые условия: тот же URL, тот же метод (GET/POST), тот же прогретый или холодный кеш, желательно из одной и той же сети. Разовый замер «на глаз» через открытие вкладки в браузере даёт слишком много шума, чтобы делать выводы.
Профилирование: где реально уходит время
Когда цифры подтвердили, что проблема есть, следующий шаг — найти, на каком этапе обработки запроса теряется время. Запрос проходит через несколько слоёв, и тормозить может любой из них: сеть (DNS, TCP/TLS-хендшейк — обычно первые десятки миллисекунд), веб-сервер (очередь на подключение, время до передачи запроса бэкенду), приложение (маршрутизация, бизнес-логика, сериализация ответа), база данных (выполнение запросов, блокировки, чтение с диска при промахе кеша) и внешние вызовы (сторонние API, очереди, объектные хранилища).
Быстрая диагностика без глубокого профилирования — включить логирование медленных запросов в базе и посмотреть на реальные тайминги:
-- MySQL: включить лог медленных запросов
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;
-- PostgreSQL: то же самое через конфиг
-- log_min_duration_statement = 500 (в postgresql.conf, в миллисекундах)
Если после нескольких минут под реальной нагрузкой лог пуст — база не узкое место, время уходит в приложении или во внешних вызовах. Если лог заполнен запросами без индекса (EXPLAIN ANALYZE покажет Seq Scan вместо Index Scan) — вот источник тормозов, и никакой апгрейд VPS его не уберёт: полное сканирование таблицы растёт вместе с данными на любом железе.
Если узкое место внутри самого кода приложения — конкретной функции, цикла, вызова ORM — нужен уже не анализ логов, а профилирование процесса на живом продакшене с минимальным оверхедом от самого замера. Как делать это безопасно, разобрано в статье про профилирование приложения на проде.
Когда дело вообще не в сервере: архитектурная проблема
Здесь стоит назвать вещи своими именами: если узкое место — это N+1 запросы к базе, отсутствие индекса на часто фильтруемом поле, отсутствие кеширования на уровне приложения (когда один и тот же тяжёлый расчёт выполняется заново на каждый запрос вместо того, чтобы один раз посчитаться и лечь в Redis), или синхронный блокирующий вызов внешнего API прямо в обработчике запроса — переезд на любое другое железо эту проблему не решит. Она архитектурная, а не инфраструктурная.
Более мощный VPS может даже замаскировать проблему на время — больше CPU и памяти позволят неэффективному коду отработать чуть быстрее, пока данных немного. Но с ростом объёма или нагрузки та же выборка снова начнёт расти в отклике, потому что её сложность привязана к количеству строк, а не к мощности сервера. Похожая история встречается и после переноса самой базы данных между серверами — иногда причина замедления в том, что при переносе потерялась статистика планировщика, и он перестаёт использовать индексы, что работали раньше; разбор такого случая — в статье про перенос базы и потерянные индексы.
Отличить архитектурную проблему от инфраструктурной просто: если при нагрузочном тесте (wrk из раздела выше) CPU и диск не заняты, а ответ всё равно медленный и растёт при росте параллельных запросов сильнее, чем линейно — это почти всегда проблема в коде, а не нехватка ресурсов сервера.
Практический план: как реализовать потенциал VPS
Если диагностика показала, что дело именно в конфигурации, а не в архитектуре приложения, — вот последовательность действий, с которой стоит начать на свежем VPS.
1. PHP: включить и настроить OPcache
; /etc/php/8.3/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.validate_timestamps=0 ускоряет продакшен, но требует ручного systemctl reload php8.3-fpm после каждого деплоя — PHP перестаёт сам проверять, изменились ли файлы.
2. PHP-FPM: рассчитать пул под реальную память сервера
; /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20 ; рассчитано по формуле из раздела выше
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
3. Nginx: буферы, keepalive, сжатие
worker_connections 2048;
http {
gzip on;
gzip_types text/css application/javascript application/json;
keepalive_timeout 15;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
4. MySQL/MariaDB: буферный пул под реальный объём памяти
# /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
innodb_buffer_pool_size = 4G # ориентировочно 60-70% RAM для выделенного под БД сервера
innodb_buffer_pool_instances = 4
Точный процент памяти под буферный пул зависит от того, живёт ли на VPS ещё и веб-сервер с приложением, или база вынесена отдельно — единой цифры нет, отталкивайтесь от объёма данных и свободной памяти после нужд остальных сервисов.
5. Добавить слой кеширования на уровне приложения, если его не было — Redis для часто читаемых, редко меняющихся данных (сессии, результаты тяжёлых выборок, счётчики). Честная оговорка: сам по себе Redis не решает проблему производительности, если данные в него кладутся без продуманной стратегии инвалидации — плохо спроектированный кеш создаёт не меньше проблем, чем его отсутствие. Кеш — это инструмент, а не автоматическое ускорение.
6. Проверить HTTP/2 и TLS-сессии — на shared-хостинге это обычно уже включено панелью, на VPS требует явной директивы в конфиге веб-сервера.
После каждого шага возвращайтесь к замерам из раздела про диагностику — TTFB и wrk-тест — и сравнивайте с исходными цифрами. Тюнинг вслепую, без замера до/после, — тот же субъективизм, только с конфигами вместо ощущений.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Стоило ли вообще переезжать на VPS, если быстрее не стало?
Да, если причиной переезда была не только скорость, а контроль: своя версия PHP, свои модули, свой cron без ограничений панели, гарантированные ресурсы. Скорость — это то, что вы получаете сверху, но только после собственной настройки, а не автоматически в момент переезда.
Сколько времени занимает базовая настройка VPS под конкретное приложение?
Зависит от стека и объёма данных — от пары часов на типовой связке nginx + PHP-FPM + MySQL для небольшого проекта до нескольких дней, если требуется профилирование кода и переработка узких мест в приложении. Откладывать этот этап на «потом» не стоит — именно он превращает изолированные ресурсы в реальную скорость.
Может ли более мощный тариф VPS решить проблему вместо тюнинга?
Иногда временно маскирует симптом, если узкое место в ресурсах. Но если проблема — запрос без индекса или N+1 в коде, апгрейд тарифа отодвигает момент, когда проблема снова станет заметна, а не убирает её причину.
Нужно ли переносить конфиги веб-сервера и базы со старого shared-хостинга на VPS?
Обычно нет — на shared-хостинге чаще всего нет доступа к системным конфигам, они настраивались провайдером на уровне всей платформы. Переносить нечего, конфигурацию под VPS нужно строить заново под характеристики именно этого сервера и профиль нагрузки.
Как понять, что тюнинг закончен и дальше упираемся в реальный потолок ресурсов?
Когда при нагрузочном тесте CPU выходит на устойчиво высокие значения, диск показывает высокую утилизацию в iostat, память в свопе или близка к исчерпанию — а в логах медленных запросов и в профиле приложения нет очевидных неоптимизированных мест. Это сигнал, что дальше помогает более мощный тариф или горизонтальное масштабирование, а не дальнейшая настройка того же сервера.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →