MAATRIX / Блог / Миф: сайт тормозит — значит, нужен сервер помощнее

Миф: сайт тормозит — значит, нужен сервер помощнее

MAATRIX

Сайт или API стал отвечать медленнее, чем хочется, — и первое решение, которое приходит в голову, звучит просто: взять тариф мощнее, добавить vCPU, накинуть RAM, пересесть на NVMe. Иногда это действительно на время снимает симптом. Но в подавляющем большинстве случаев причина медленности лежит не в нехватке железа, а в том, как код и запросы к базе данных используют то железо, что уже есть, — и апгрейд просто откладывает момент, когда проблема вернётся, уже на более мощном и более дорогом сервере.

Откуда берётся этот миф

Идея «мало ресурсов — сайт тормозит» интуитивно понятна и на бытовом уровне даже верна: если сервер реально упирается в CPU или RAM, добавление ресурсов помогает почти всегда. Провайдеры хостинга усиливают эту интуицию самой формой тарифной сетки — планы отличаются друг от друга числом ядер, объёмом памяти и типом диска, и естественно думать, что более высокий план по этим параметрам решит любую проблему производительности, раз уж это единственные рычаги, которые видны в панели заказа.

Проблема в том, что современный веб-сайт или API тормозит по причинам, которые с «нехваткой железа» связаны лишь частично:

  • сетевой round-trip и TTFB — время до первого байта ответа, которое складывается из работы сети, приложения и базы, а не только из вычислительной мощности;
  • алгоритмическая неэффективность кода — N+1-запросы к базе, O(n²) обработка в цикле, синхронные блокирующие вызовы внешних API;
  • отсутствие или неправильные индексы в базе данных — запрос, который должен занимать миллисекунды, делает полный скан таблицы;
  • отсутствие кеширования повторяющихся дорогих вычислений — тема отдельного мифа, кеш решит проблему с производительностью, где разбирается обратная сторона той же ошибки;
  • архитектурные узкие места — единая точка последовательной обработки, блокировки на уровне строк в БД, синхронный вызов платёжного шлюза прямо в теле HTTP-запроса.

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

Почему апгрейд иногда действительно помогает — и почему временно

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

Больше RAM маскирует проблему на уровне дискового I/O. Если рабочий набор данных (то, что реально читается запросами) не помещается в оперативную память, СУБД или ОС вынуждены постоянно ходить на диск. Увеличение RAM расширяет buffer pool (innodb_buffer_pool_size в MySQL, shared_buffers в PostgreSQL) или страничный кеш ОС — и часть запросов, которые раньше требовали чтения с диска, начинают попадать в память. Отклик становится быстрее, метрики зеленеют. Но это работает лишь до тех пор, пока объём данных не перерастёт новый потолок RAM — а он перерастёт при обычном росте бизнеса, и тормоза вернутся на том же самом неоптимизированном запросе, только теперь уже на более дорогом тарифе.

Больше ядер маскирует проблему на уровне конкурентности, а не задержки одного запроса. Если один запрос синхронно ждёт 800 мс на медленный SQL-запрос без индекса, добавление ядер не сделает этот конкретный запрос быстрее — он всё так же будет ждать 800 мс. Что изменится — это способность сервера обрабатывать больше таких медленных запросов *одновременно*, не ставя их в очередь друг за другом. При низкой нагрузке разница незаметна, кажется, что «стало быстрее». При росте трафика узкое место — тот же самый медленный запрос — просто проявляется резче, потому что теперь десятки параллельных медленных запросов конкурируют за одну и ту же таблицу и её блокировки.

Итог: апгрейд не устраняет причину — он расширяет буфер, в который причина может прятаться. Чем больше буфер, тем позже вы увидите проблему снова, но тем дороже она обойдётся к моменту, когда всё-таки проявится — на трафике, который уже привык к текущей производительности.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Что на самом деле чаще всего тормозит сайт

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

СимптомЧастая настоящая причинаЧто не поможет
Страница со списком грузится секундамиN+1-запросы: на каждую строку списка — отдельный запрос к БДБольше CPU/RAM — количество запросов к базе не изменится
API отвечает медленно только под нагрузкойБлокировки строк в БД при конкурентных UPDATE на одну и ту же записьБольше ядер — очередь на блокировку останется той же
Первый запрос после деплоя долгий, потом быстрее«Холодный» кеш приложения или прогрев JIT/пулов соединенийАпгрейд диска — проблема не в I/O, а в прогреве
Медленно только определённые отчёты/фильтрыОтсутствие индекса под конкретную комбинацию WHERE-условийБольше RAM снизит эффект, но не уберёт full scan
Сайт «подвисает» на внешних интеграциях (платежи, email, SMS)Синхронный вызов стороннего API прямо в обработчике запроса без таймаутаМощность сервера тут вообще ни при чём — ждёте чужой сервер

Наглядный пример N+1 на псевдокоде ORM — то, что легко пропустить в ревью, потому что каждая отдельная строка выглядит невинно:

# Плохо: 1 запрос за список + N запросов за автора каждого поста
posts = Post.objects.all()
for post in posts:
    print(post.author.name)  # отдельный SELECT на каждой итерации

# Хорошо: тот же результат одним JOIN'ом
posts = Post.objects.select_related('author').all()

На таблице в 20 строк разницы почти не видно. На таблице в 5000 строк разница — между одним запросом и пятью тысячами, и никакой апгрейд сервера не превращает 5000 последовательных round-trip к базе в один.

Как найти реальную причину, прежде чем платить за апгрейд

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

1. Разложите TTFB на составляющие. Прежде чем что-либо чинить, убедитесь, что медленно именно приложение, а не сеть до него:

curl -o /dev/null -s -w \
'DNS: %{time_namelookup}s  TCP: %{time_connect}s  TLS: %{time_appconnect}s  TTFB: %{time_starttransfer}s  Total: %{time_total}s\n' \
https://example.com/

Если основное время уходит в time_starttransfer (время до первого байта ответа), проблема внутри приложения или базы — переходите к следующим шагам. Если время съедают time_connect/time_appconnect, дело в сети или TLS-хендшейке, и апгрейд сервера тут действительно ни при чём.

2. Проверьте, действительно ли ресурсы сервера упираются в потолок. Если CPU простаивает, а память свободна — апгрейд гарантированно не поможет, каким бы медленным ни был сайт.

vmstat 1 5
iostat -xz 1 5

Смотрите на wa (iowait) в vmstat — высокий iowait при низком us/sy говорит о том, что процессор ждёт диск, а не считает; на %util в iostat — близкое к 100% при заметном await означает, что диск действительно узкое место. Если же us+sy далеки от 100%, а свободной памяти достаточно, сервер простаивает, и тормозит явно не он.

3. Найдите конкретный медленный запрос к базе. Для PostgreSQL:

SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Для MySQL — включите slow query log и разберите его агрегатором:

mysql -e "SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 0.5;"
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

Запрос, который стабильно попадает в топ по суммарному времени выполнения, — первый кандидат на EXPLAIN ANALYZE и добавление индекса, а не на апгрейд.

4. Профилируйте само приложение. Медленный SQL — не единственный источник задержки: тяжёлый рендеринг шаблона, синхронная сериализация большого JSON или блокирующий вызов внешнего API дают ту же картину «сайт тормозит» без единого лишнего запроса к базе. Разбор инструментов профилирования на живом продакшене (APM, sampling-профилировщики, логирование по этапам) — в статье профилирование приложения на проде. Если после проверки диска, базы и профиля приложения причина всё ещё не найдена, стоит пройтись по менее очевидным источникам скрытой медленности — восемь таких причин, которые обычно не проверяют первыми, разобраны в статье «всё работает, но медленно».

Когда апгрейд сервера — действительно правильный шаг

Диагностика не всегда заканчивается словами «дело в коде». Есть сценарии, где более мощный сервер — честное и обоснованное решение:

  • Рабочий набор данных объективно вырос — сайт при запуске обслуживал 10 тысяч товаров, а спустя два года их 500 тысяч, и та же схема с теми же индексами уже не помещается в старый объём RAM даже без изменений в коде.
  • Нагрузка выросла легитимно, а код и запросы уже оптимизированы — индексы на месте, N+1 устранены, кеш настроен под профиль данных, но количество одновременных пользователей превысило то, что был рассчитан выдержать текущий тариф.
  • Задача действительно CPU-bound и уже распараллелена корректно — например, генерация превью изображений или пакетная обработка видео, где узкое место — реальные вычисления, а не ожидание диска или сети.
  • Диск реально не успевает после того, как убраны лишние операции записи (избыточное логирование, неоптимальные fsync), а рабочая нагрузка по I/O объективно превышает возможности текущего носителя.

Разница между этими случаями и мифом — в порядке действий, а не в самом факте апгрейда: здесь к решению «взять сервер мощнее» пришли *после* диагностики и оптимизации, а не вместо них. Апгрейд, сделанный на этом этапе, решает настоящую проблему, а не откладывает её.

Порядок действий: сначала дешёвая диагностика, потом дорогое железо

Экономически апгрейд — это постоянные ежемесячные расходы, а найти и исправить конкретный запрос или добавить индекс — разовая работа. Разумная последовательность:

  1. Измерьте, где реально уходит время — TTFB по этапам, vmstat/iostat, APM или логирование времени по стадиям обработки запроса.
  2. Найдите конкретное узкое место — самый тяжёлый запрос по pg_stat_statements/slow log, самую медленную функцию по профилировщику.
  3. Исправьте на уровне кода или схемы — добавьте индекс, устраните N+1, вынесите синхронный внешний вызов в очередь, добавьте кеш там, где данные читаются часто и меняются редко.
  4. Измерьте снова — убедитесь, что метрика реально сдвинулась, а не просто «стало субъективно быстрее».
  5. Только если после этого сервер объективно упирается в CPU, RAM или диск — берите тариф мощнее, уже понимая, какой именно ресурс и насколько нужно увеличить, а не наугад.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Как быстро понять, стоит ли вообще тратить время на диагностику, или проще сразу проапгрейдить?

Один прогон vmstat 1 5 и iostat -xz 1 5 во время пиковой нагрузки занимает минуту и сразу отвечает на вопрос: если CPU и диск не близки к 100%, апгрейд точно не поможет, и время на диагностику окупится. Если ресурсы объективно на пределе — тогда апгрейд обоснован и без долгого разбора кода.

Может ли апгрейд сделать хуже?

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

Что делать, если оптимизация кода невозможна прямо сейчас — сроки поджимают?

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

Какой ресурс обычно упирается первым — CPU, RAM или диск?

Единого правила нет, это зависит от профиля нагрузки: у сайтов с большим числом мелких запросов к базе чаще упирается диск или RAM (buffer pool/page cache), у сервисов с тяжёлыми вычислениями на запрос — CPU. Именно поэтому диагностика важнее интуиции: угадать без измерения, во что упирается конкретно ваш сервер, обычно не получается.

Кеширование — это решение проблемы медленного сайта?

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

А что насчёт мифа про количество ядер отдельно от общей темы апгрейда?

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

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →