Что дешевле держать под нагрузкой: сравнение стеков
Дешёвый сервер не всегда означает дешёвый стек. Сравниваем Django, Node.js и Go по расходам на CPU, базу данных, масштабирование и поддержку — без выдуманных бенчмарков.

При одинаковом трафике стоимость приложения определяется не только ценой виртуальной машины: в счёт входят база данных, запас по CPU и памяти, мониторинг, время инженеров и цена аварий. Django 5.2, Node.js 22 LTS и Go 1.23 могут обслуживать один и тот же API, но требуют разного запаса инфраструктуры и по-разному ломаются под нагрузкой.
Что именно сравнивать, а не только язык
Популярное решение — выбрать самый быстрый рантайм, а затем уменьшать размер сервера. Это часто даёт неверный результат. Если приложение упирается в PostgreSQL, внешнее API или медленные запросы, разница между языками будет меньше, чем стоимость одной плохо настроенной транзакции.
Для сравнения нужен одинаковый контур:
- одинаковая бизнес-логика и формат ответа;
- одна версия PostgreSQL, например 16;
- одинаковые лимиты соединений и размер данных;
- один тип нагрузки: чтение, запись или смешанный сценарий;
- одинаковые требования к доступности и резервированию.
RPS1 сам по себе ничего не говорит о цене. Важно, сколько запросов стек выдерживает при заданной задержке, ошибках и потреблении памяти.
Самый дешёвый стек под нагрузкой — не тот, у которого минимальный расход CPU, а тот, который оставляет запас и не требует постоянного ручного обслуживания.
Три стека и их реальная цена
Django 5.2 и PostgreSQL 16
Django выгоден там, где большую часть стоимости проекта составляет разработка, а не вычисления. Встроенные модели, миграции, административная панель, авторизация и понятная структура сокращают время вывода продукта. Для каталога, личного кабинета, CRM и обычного API это часто важнее разницы в потреблении CPU.
Цена проявляется при росте параллельных запросов. Каждый процесс приложения занимает память, а тяжёлые синхронные операции удерживают рабочий процесс дольше. Масштабирование обычно начинается с нескольких процессов за reverse proxy, затем добавляются кэш, очередь задач и отдельные воркеры.
Главный риск — пытаться лечить медленный ORM увеличением числа процессов. Так можно быстро съесть RAM и одновременно создать очередь соединений к PostgreSQL. Перед масштабированием нужно проверить SQL, индексы и время внешних вызовов.
Node.js 22 LTS и PostgreSQL 16
Node.js часто экономичен для API с большим числом коротких сетевых операций: процесс может обслуживать множество соединений, пока не блокируется синхронной работой. Это удобно для BFF, шлюзов, чатов и сервисов, которые большую часть времени ждут базу или внешний HTTP-сервис.
Экономия исчезает, если в обработчик попадает тяжёлое вычисление, большой JSON или синхронная файловая операция. Один блокирующий участок задерживает другие запросы в том же цикле событий. Тогда приходится выносить расчёты в worker-процессы, очередь или отдельный сервис, а это уже дополнительные контейнеры, логи и мониторинг.
У Node.js ниже порог запуска команды, но выше цена дисциплины: нужно контролировать версии зависимостей, лимит памяти, утечки и поведение event loop. Для небольшого проекта это может быть дешевле Django, а для команды без практики профилирования — дороже.
Go 1.23 и PostgreSQL 16
Go обычно выбирают, когда важны низкое потребление памяти на один процесс, предсказуемые задержки и простая упаковка приложения в один бинарный файл. Это сильный вариант для сетевых сервисов, прокси, обработчиков очередей и API с высокой долей собственного CPU-кода.
Инфраструктурная экономия не отменяет стоимости разработки. В Go нет встроенной админки и такого объёма готового прикладного каркаса, как в Django. Команде придётся отдельно выбрать решения для миграций, валидации, логирования, авторизации и фоновых задач, а затем поддерживать их совместимость.
Go не спасёт сервис, который ждёт медленный запрос к базе. Если база отвечает 300 мс, более дешёвый CPU не сделает запрос быстрым. В таком сценарии сначала ищут блокировки, планы запросов и лишние round trip, а не переписывают обработчик.
Сравнение по статьям расходов
| Стек | Где обычно выигрывает | Что увеличивает счёт | Когда выбор оправдан |
|---|---|---|---|
| Django 5.2 | Разработка и типовые бизнес-функции | Память процессов, тяжёлые ORM-запросы, фоновые задачи | Нужен быстрый запуск продукта и много стандартной логики |
| Node.js 22 LTS | Сетевой I/O и большое число коротких запросов | Блокирующий код, worker-процессы, сложный контроль памяти | Команда уже работает с TypeScript и сервисами на JavaScript |
| Go 1.23 | Плотность размещения и предсказуемость сервиса | Разработка прикладных компонентов и сопровождение платформы | Нагрузка высокая, API стабилен, инфраструктурная эффективность важнее скорости MVP |
Таблица не заменяет замеры. Цены виртуальных машин, дисков, балансировщиков и managed PostgreSQL зависят от провайдера, региона и модели оплаты. Поэтому фиксировать универсальную сумму «в месяц» для стека некорректно.
Как считать стоимость на своём проекте
Считайте не цену одного контейнера, а полную стоимость контура. Для каждого варианта зафиксируйте одинаковые требования: целевую задержку, допустимый процент ошибок, количество запросов в секунду, размер базы и окно пикового трафика.
- Соберите минимальный одинаковый сервис. Один endpoint должен выполнять одну и ту же операцию и обращаться к одной тестовой базе. Уберите кэш на первом прогоне, иначе вы сравните кэш, а не стек.
- Зафиксируйте окружение. Запишите тип CPU, объём RAM, версию ОС, PostgreSQL, настройки пула соединений и лимиты контейнера. Без этого результаты нельзя повторить.
- Проведите ступенчатую нагрузку. Увеличивайте параллельность, пока задержка p95 не выйдет за допустимый предел или доля ошибок не станет неприемлемой. Один короткий прогон не показывает поведения под длительной нагрузкой.
- Снимите профиль расходов. Смотрите CPU, память, сетевой трафик, количество соединений к базе, задержки SQL и стоимость фоновых задач. Для базы отдельно проверьте диск и резервные копии.
- Посчитайте запас. Если вариант работает только при почти полном использовании CPU, он не дешевле: ближайший пик потребует срочного масштабирования. Добавьте заранее согласованный запас и сравните итоговую месячную стоимость.
Для нагрузочного теста используйте знакомый инструмент, например k6 или JMeter, но не смешивайте генератор нагрузки с сервером приложения. Иначе CPU генератора станет скрытым ограничением.
Когда что выбирать
Берите Django, если дороже всего время команды
Это рациональный выбор для продукта с большим количеством CRUD-операций, ролей, форм и внутренних интерфейсов. Сначала оптимизируйте запросы и вынесите долгие задачи из HTTP-обработчика. Переписывать сервис на Go только ради меньшего RSS обычно невыгодно, пока не посчитана стоимость разработки и миграции.
Берите Node.js, если нагрузка в основном ждёт сеть
Node.js подходит для API-шлюза, уведомлений и сервисов, которые соединяют несколько внешних систем. Установите правила для синхронного кода и следите за event loop. Если в запросах появляются изображения, архивы, большие отчёты или криптографические вычисления, вынесите их из основного процесса.
Берите Go, если ограничение уже видно в инфраструктуре
Go оправдан, когда профилирование показывает, что приложение упирается именно в CPU или память, а не в PostgreSQL и внешние сервисы. Он также полезен для небольших самостоятельных сервисов, которые нужно плотно размещать на хостах. Если продукт ещё меняет доменную модель каждую неделю, выигрыш рантайма может не окупить стоимость менее готового прикладного слоя.
Что ломается первым
- PostgreSQL. Пул приложения открывает больше соединений, чем база может обслужить. Результат — ожидание, рост p95 и ошибки подключения.
- Память. Увеличение числа процессов или контейнеров без контроля лимитов приводит к OOM-kill. Особенно быстро это видно на Django с тяжёлыми импортами и на Node.js с большими объектами.
- Очередь задач. Фоновые операции начинают конкурировать с HTTP за CPU, диск или соединения к базе. Их нужно измерять как отдельный контур.
- Наблюдаемость. Без трассировки и метрик команда видит только «медленно», но не знает, где потрачено время. Дешёвый сервер превращается в дорогой поиск причины инцидента.
Не сравнивайте только максимальный RPS. Сопоставляйте стоимость запроса при нужной задержке, частоту ошибок, время релиза и часы сопровождения. Если приложение проводит большую часть времени в базе, смена языка почти наверняка не будет первым рычагом.
Что делать дальше
Составьте маленький стенд из трёх реализаций одного критичного сценария и измерьте его на вашем объёме данных. В отчёте сохраните p50 и p95 задержки, CPU, память, соединения к PostgreSQL и цену инфраструктуры за месяц. После этого отдельно оцените время команды на релиз, диагностику и обновление зависимостей — именно эти расходы часто меняют победителя.
1 RPS (requests per second) — число запросов, которое сервис обрабатывает за секунду. Показатель имеет смысл только вместе с задержкой, ошибками и описанием сценария.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Django 5.2: Deployment checklist, Node.js: официальная страница предыдущих релизов
Частые вопросы
Какой стек самый дешёвый для небольшого веб-сервиса?
Правда ли, что Go всегда дешевле Python и Node.js?
Нужно ли переписывать Django-приложение, если вырос трафик?
Что будет, если я сравню стеки на другой версии Node.js, Django или Go?
Почему нагрузочный тест показывает хороший RPS, а в проде всё медленно?
Какой показатель смотреть первым после запуска?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.