Serverless-архитектура: когда функции выгоднее серверов и как посчитать стоимость

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

Serverless обещает простую сделку: вы пишете функцию, облако запускает её по событию и берёт деньги только за время работы. Для одних задач это действительно самый дешёвый и быстрый способ запустить код. Для других — источник неожиданно большого счёта, задержек на холодном старте и архитектуры, которую трудно отлаживать. Разница определяется не модой, а профилем нагрузки и характером задачи. Ниже — как устроена бессерверная модель, какие платформы доступны российским компаниям, как посчитать стоимость до разработки, в каких сценариях функции выигрывают у серверов и контейнеров, а в каких проигрывают, и какие инженерные проблемы нужно решить до запуска в продакшен. Что такое serverless на самом деле Серверы никуда не исчезают: ими управляет облачный провайдер. Команда не выбирает размер виртуальной машины, не обновляет операционную систему и не настраивает автомасштабирование. Она описывает код и событие, которое его запускает, а платформа сама поднимает нужное количество экземпляров и останавливает их, когда вызовов нет. Под словом serverless обычно понимают две группы сервисов: Функции как сервис (FaaS) — код в виде обработчика, который запускается по HTTP-запросу, сообщению из очереди, загрузке файла или расписанию. Управляемые сервисы без серверов — базы данных, очереди, API-шлюзы и хранилища, где оплата зависит от объёма операций, а не от выделенных ресурсов. Отдельно стоят бессерверные контейнеры: вы поставляете образ контейнера, а платформа запускает его по запросам и масштабирует до нуля. Это удобный промежуточный вариант, когда код не укладывается в ограничения функций или его не хочется переписывать под конкретную платформу. Модель исполнения: что нужно понимать до выбора Холодный старт Если свободного экземпляра функции нет — например, после простоя или при резком росте нагрузки, — платформе нужно его подготовить: выделить окружение, загрузить код, выполнить инициализацию. Первый вызов на новом экземпляре обрабатывается заметно дольше последующих. Длительность зависит от среды выполнения, размера пакета и того, что делает код при старте, поэтому её измеряют на своём коде, а не берут из чужих бенчмарков. Отсутствие состояния Экземпляр функции может быть остановлен в любой момент, а следующий вызов попадёт на другой экземпляр. Всё, что должно сохраниться, хранится снаружи: в базе данных, объектном хранилище, кэше. Переиспользовать между вызовами можно только то, что безопасно потерять, — например, открытое соединение с базой. Ограничения платформы У каждой платформы есть пределы на длительность выполнения, объём памяти, размер пакета, размер запроса и ответа, число одновременных экземпляров. Задача, которая в них не укладывается, потребует либо разбиения на шаги, либо другой модели исполнения. Платформы, доступные в России Yandex Cloud Functions Самая развитая FaaS-платформа российского облака. По документации Yandex Cloud на сентябрь 2026 года, среди поддерживаемых сред выполнения — Node.js 22, Python 3.12 и 3.14, Go 1.23, Java 21. Экземпляру можно выделить до 8 ГБ памяти. Максимальное время выполнения — до часа, но таймаут больше десяти минут доступен только для функций в режиме длительного выполнения. Функции запускаются по HTTP, через API Gateway, по сообщениям из очередей, событиям объектного хранилища и таймерам. Для снижения холодных стартов есть подготовленные экземпляры, простой которых оплачивается отдельно. Для кода, который удобнее поставлять контейнером, в той же экосистеме есть Serverless Containers. Cloud.ru На платформе Cloud.ru Advanced доступен сервис FunctionGraph — бессерверные функции с запуском по событиям и поддержкой Python, Node.js и Java. Перед выбором стоит сверить с актуальной документацией набор триггеров, лимиты и доступность сервиса в нужном регионе. VK Cloud и собственный Kubernetes VK Cloud в своих материалах описывает бессерверные сценарии через контейнеры и управляемый Kubernetes с открытыми инструментами вроде OpenFaaS. Тот же путь подходит, если нужной управляемой FaaS-платформы нет или требуется размещение в собственном контуре: бессерверную модель разворачивают поверх Kubernetes с помощью открытых проектов — например, Knative или OpenFaaS. Это даёт масштабирование до нуля и перенос между облаками, но управление кластером и самой платформой остаётся на вашей команде, и часть экономической выгоды serverless теряется. Зарубежные платформы AWS Lambda остаётся эталоном по возможностям: тарификация по миллисекундам, выполнение до 15 минут, подготовленная конкурентность и SnapStart для ускорения старта. Однако с марта 2022 года AWS не принимает новых клиентов из России, а для обработки персональных данных россиян действуют требования о локализации. Для большинства российских B2B-проектов зарубежные облака — не вариант по юридическим причинам. Как выстраивать стек с учётом этих ограничений, мы разбирали в статье об импортозамещении digital-стека . Как посчитать стоимость до разработки Облачные тарифы меняются, поэтому считать нужно не по цифрам из статей, а по методике с актуальными ценами из прайса провайдера. Вот как это делается для функций. Из чего складывается счёт Вызовы. Оплата за каждый миллион вызовов. Вычисления. Выделенная память, умноженная на время выполнения. В Yandex Cloud Functions единица — ГБ×час, а время выполнения округляется вверх до 100 мс. Подготовленные экземпляры. Если вы держите прогретые экземпляры, их простой оплачивается независимо от вызовов. Исходящий трафик. Сопутствующие сервисы. API-шлюз, очереди, базы данных, хранилище, логи и мониторинг. В реальных проектах эта часть нередко больше, чем сами функции. У многих платформ есть бесплатный ежемесячный объём. В Yandex Cloud Functions это первый миллион вызовов и первые 10 ГБ×час вычислений; неиспользованный остаток на следующий месяц не переносится. Формула Вычисления, ГБ×час = число вызовов × длительность (с, с учётом округления) × память (ГБ) / 3600 Стоимость в месяц = (вызовы − бесплатные вызовы) / 1 000 000 × цена за млн вызовов + (ГБ×час − бесплатные ГБ×час) × цена ГБ×час + подготовленные экземпляры × часы простоя × их цена + трафик + API-шлюз + очереди + хранилище + логи Пример расчёта объёма Возьмём внутренний B2B-сервис: в рабочие часы приходит в среднем 50 запросов в секунду, обработка занимает до 100 мс, функции выделено 256 МБ. Рабочих часов в месяце — примерно 22 дня по 9 часов, то есть 712 800 секунд. Вызовы: 50 × 712 800 = 35 640 000 в месяц Вычисления: 35 640 000 × 0,1 с × 0,25 ГБ = 891 000 ГБ×с ≈ 247,5 ГБ×час Эти объёмы умножаются на действующие тарифы. Для сравнения нужен второй расчёт: сколько виртуальных машин или узлов кластера потребуется под пиковую нагрузку с запасом на отказ одной машины, сколько часов в месяце они работают (все 720, а не только рабочие) и сколько стоят балансировщик, мониторинг и время инженера на обслуживание. Как читать результат Функции оплачиваются только за работу, серверы — за время существования. Поэтому решающий параметр — утилизация: какую долю времени выделенные ресурсы были бы реально заняты. Нагрузка с длинными простоями — ночи, выходные, редкие события. Функции почти всегда дешевле: в простое вы не платите ничего. Нагрузка с резкими пиками. Сервер пришлось бы держать под пик, функции масштабируются под фактический поток. Выигрыш зависит от соотношения пика и среднего. Ровная высокая нагрузка круглые сутки. Выделенные ресурсы загружены почти полностью, и платить за каждое ГБ×час по тарифу функций становится дороже, чем за постоянно работающие машины или контейнеры. Отдельно считайте тяжёлые вычисления: инференс нейросетей, обработку видео, задачи с большим объёмом памяти и долгим выполнением. Там стоимость ГБ×час умножается на большие числа, а для графических ускорителей обычно нужна другая модель — выделенные серверы или контейнеры. Стоимость облака — лишь часть бюджета продукта. Как складывается полная стоимость разработки и эксплуатации, мы разобрали в статье о стоимости разработки веб-платформы . Где serverless даёт реальную выгоду Обработка файлов и событий Файл загружен в объектное хранилище — функция создаёт превью, распознаёт текст, проверяет формат и записывает результат. Нагрузка нерегулярная, каждая операция независима, параллельная обработка получается сама собой. // Yandex Cloud Functions, Node.js: обработка события загрузки в Object Storage module.exports.handler = async function (event, context) { for (const message of event.messages) { const { bucket_id: bucket, object_id: key } = message.details; const source = await downloadObject(bucket, key); const preview = await makePreview(source); // например, через sharp await uploadObject(bucket, `previews/${key}`, preview); await markAsProcessed(key); } return { statusCode: 200 }; }; Функции downloadObject , makePreview , uploadObject и markAsProcessed — ваш код поверх S3-совместимого SDK и базы данных. Вебхуки и интеграции Приём уведомлений от платёжных сервисов, CRM, мессенджеров. Объём небольшой, время прихода непредсказуемо. Правильная схема — функция быстро проверяет подпись, кладёт событие в очередь и отвечает, а тяжёлую обработку выполняет другой обработчик. Если интеграций много, каждая живёт в отдельной функции и не ломает остальные при ошибке. Задачи по расписанию Ночные выгрузки, синхронизация справочников, отчёты, очистка устаревших данных. Держать ради них постоянно работающий сервер нерационально, а функция по таймеру стоит копейки или укладывается в бесплатный объём. API с неравномерной нагрузкой Внутренние сервисы, которыми пользуются в рабочее время, сезонные акции, промо-страницы с всплесками трафика. Функции за API-шлюзом масштабируются автоматически и не требуют планирования мощностей. Прототипы и проверка гипотез Когда нагрузка неизвестна, а скорость запуска важнее идеальной архитектуры, функции позволяют запустить сервис без настройки инфраструктуры. Если гипотеза подтвердится и нагрузка станет ровной, сервис переносится в контейнеры — при условии, что бизнес-логика изначально отделена от платформы. Где serverless проигрывает Ровная высокая нагрузка. Постоянно занятые ресурсы дешевле арендовать целиком. Жёсткие требования к задержке каждого запроса. Холодный старт можно сгладить подготовленными экземплярами, но за них платят и в простое, и экономия уменьшается. Долгие вычисления и специальное железо. Задачи на десятки минут, графические ускорители, большие объёмы памяти. Постоянные соединения. Сценарии, где клиент долго держит открытое соединение, плохо ложатся на модель коротких вызовов. Сложная логика с состоянием. Длинные транзакции и процессы, которым нужна локальная память между шагами. Требования к изоляции и аудиту. В отраслях с жёстким регулированием проверьте заранее, закрывает ли платформа требования к сертификации и контролю окружения. Инженерные проблемы и как их решать Холодный старт Уменьшайте пакет: только нужные зависимости, сборка с удалением неиспользуемого кода. Выносите тяжёлую инициализацию из кода, который выполняется на каждый вызов, и переиспользуйте её результаты. Для критичных функций включайте подготовленные экземпляры и считайте их стоимость отдельно. Измеряйте долю холодных вызовов и задержку по перцентилям, а не среднее время. Соединения с базой данных При всплеске нагрузки платформа запускает сотни экземпляров, и каждый открывает свои соединения. Реляционная база быстро исчерпывает лимит. Решения: маленький пул внутри экземпляра, пулер соединений перед базой, базы данных с HTTP-доступом или бессерверным режимом. // Пул создаётся один раз на экземпляр и переиспользуется между вызовами const { Pool } = require('pg'); let pool; function getPool() { if (!pool) { pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 2, // мало соединений на экземпляр idleTimeoutMillis: 10000, }); } return pool; } module.exports.handler = async function (event) { const { rows } = await getPool().query('SELECT id, status FROM orders WHERE id = $1', [event.queryStringParameters.id]); return { statusCode: 200, body: JSON.stringify(rows[0] ?? null) }; }; Привязка к провайдеру Формат событий, триггеры и