Термины и контекст: почему “оплата по факту” всё равно приводит к сюрпризам
Многие помнят старую логику такси: пока поездка идёт, счётчик продолжает считать, а итоговая сумма зависит не только от маршрута, но и от пробок, ожидания и других факторов по пути. С serverless работает похожий принцип: формально вы платите по факту использования, но итоговый счёт не всегда оказывается таким предсказуемым, как кажется в начале.
Serverless — это модель, в которой приложение использует управляемые облачные сервисы и функции, запускаемые по событию, а команде не нужно вручную держать и обслуживать постоянно работающие серверы под каждую задачу. Иначе говоря, вы работаете не с сервером как таковым, а с логикой выполнения: произошло событие, код отработал, платформа выделила ресурсы и затем освободила их.
На старте такая схема выглядит почти идеальной: не нужно держать мощности про запас, платить за простой и заранее угадывать нужный объём ресурсов. Но “оплата по факту” не означает ни автоматически низких, ни полностью предсказуемых расходов. Она лишь означает, что счёт напрямую зависит от реальной активности системы.
На практике расходы растут из нескольких источников сразу:
- Как часто запускается код;
- Сколько длится выполнение;
- Сколько памяти выделено;
- Какие дополнительные сервисы участвуют в обработке;
- Насколько хорошо команда видит стоимость отдельных сценариев.
Именно поэтому serverless легко недооценить, если смотреть только на цену одной функции. На деле один пользовательский запрос может пройти через API Gateway, вызвать функцию, обратиться к базе данных, записать логи, отправить событие в очередь и запустить следующий шаг обработки. В итоге счёт складывается не из одной операции, а из целой цепочки.
Пока нагрузка умеренная, такая архитектура выглядит лёгкой и экономичной. Но при росте числа вызовов, длительности выполнения, объёма памяти и числа зависимых сервисов стоимость начинает расти сразу в нескольких точках. Поэтому serverless действительно помогает не платить за простой и снимает часть инфраструктурной рутины, но делает расходы более чувствительными к архитектуре, событиям и качеству наблюдаемости.
А сколько евро стоит каждый ваш километр?

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

После количества вызовов в дело вступают другие параметры: сколько длится каждое выполнение и сколько ресурсов оно получает. Даже если запусков немного, итоговый счёт всё равно может расти, когда функции работают слишком долго или получают больше памяти, чем им реально нужно.
В serverless это особенно важно, потому что стоимость зависит не только от самого факта запуска, но и от времени выполнения и объёма выделенной памяти. Иначе говоря, платформа учитывает не просто запуск, а ещё и то, насколько “тяжёлым” оказалось само выполнение.
С длительностью логика относительно простая: чем дольше работает функция, тем выше стоимость. Но на практике время часто накапливается из-за мелочей: неудачных запросов к базе, лишних обращений к внешним API, тяжёлой сериализации, избыточной логики внутри одной функции или неэффективной работы с очередями и ретраями. В тестовой среде это может выглядеть терпимо, а в продакшене становиться стабильным источником лишних расходов.
С памятью ситуация чуть коварнее. Её нередко выделяют с запасом по принципу “пусть лучше будет больше, чем не хватит”. Для надёжности это понятно, но для бюджета быстро становится проблемой: чем больше памяти выделено функции, тем дороже обходится каждое выполнение. Особенно заметно это в сценариях с большим числом вызовов, где даже небольшой запас сверху масштабируется в ощутимую сумму.
Поэтому при оптимизации полезно проверять сразу две вещи:
- Достаточно ли быстро функция завершает работу;
- Не выделено ли ей больше памяти, чем нужно на практике.
Хорошая практика — не задавать параметры “на глаз”, а проверять их на реальных сценариях. Если функция стабильно укладывается в меньший объём памяти и не теряет в скорости, переплата оказывается лишней. А если она долго работает даже при разумной конфигурации, искать причину нужно уже в логике, зависимостях или архитектуре вызова.
Именно поэтому длительность и память стоит рассматривать вместе: одна показывает, сколько времени функция остаётся в работе, вторая — насколько дорогим оказывается это время. В сумме они часто влияют на счёт сильнее, чем кажется на старте.
Зависимые сервисы: где счёт начинает расти за пределами одной функции
Но даже вызовы, длительность и память — это ещё не весь счёт. В serverless функция редко живёт изолированно: один запуск может пройти через API Gateway, обратиться к базе данных, записать логи, отправить сообщение в очередь, сохранить файл в хранилище или запустить следующий этап обработки. Для продукта это выглядит как единый сценарий, а для облачного счёта — как несколько отдельных источников расходов.
Именно поэтому serverless может казаться дешёвым на уровне одной функции и неожиданно дорогим на уровне всего процесса. Команда видит приемлемую цену выполнения, но не замечает, что рядом постоянно оплачиваются запросы к БД, операции в очередях, логирование, хранение данных и сетевое взаимодействие между сервисами. В итоге функция оказывается не главным источником затрат, а точкой входа в более длинную цепочку.
Особенно заметно это в архитектурах, где одно событие запускает несколько зависимых процессов без явного контроля стоимости. Например, загрузка файла может вызвать обработку метаданных, запись в базу, генерацию превью, отправку уведомления, логирование и синхронизацию с другим сервисом. Для пользователя это одно действие, а для облака — уже набор платных операций.
Поэтому при оптимизации важно смотреть шире самой функции и считать стоимость всей цепочки. Если выполнение стало чуть дешевле, но рядом продолжают бесконтрольно расти логи, запросы к БД или число событий в очередях, экономия будет скорее косметической.
Хороший признак зрелого подхода — когда команда умеет оценивать не только стоимость отдельного запуска, но и полную цену бизнес-действия: например, одной загрузки файла, одной регистрации пользователя, одного заказа или одной обработки изображения.
Практики оптимизации: как снижать стоимость на уровне функций, событий и архитектуры

После того как мы разобрали, из-за чего растёт serverless-счёт, логично перейти к следующему вопросу: что с этим делать на практике. Обычно оптимизация не сводится к одной “волшебной кнопке”, а даёт результат там, где команда наводит порядок сразу на нескольких уровнях: внутри функций, в событийной логике и в архитектуре в целом.
Это можно представить так:
| Уровень | Что оптимизировать | Что это даёт |
| Функции | Сокращать время выполнения, точнее подбирать память, убирать лишнюю логику из одного запуска | Каждый отдельный вызов обходится дешевле |
| События | Фильтровать лишние триггеры, уменьшать “шум”, не запускать обработку там, где она не нужна | Снижается общее число вызовов и фоновых операций |
| Архитектура | Убирать лишние промежуточные шаги, пересматривать декомпозицию, считать стоимость всей цепочки, а не одной функции | Меньше сервисов и переходов участвует в одном бизнес-действии |
На уровне функций обычно сокращают лишние вычисления, уменьшают число ненужных обращений к внешним сервисам, убирают тяжёлые зависимости и подбирают память ближе к реальной нагрузке. Здесь часто работает простая дисциплина: меньше лишнего внутри одного запуска — ниже стоимость каждого выполнения.
На уровне событий задача в другом: запускать только то, что действительно нужно. Если система реагирует на слишком много вторичных сигналов, дублирует обработчики или плодит лишние фоновые операции, счёт начинает расти даже при нормальном трафике. Поэтому заметный эффект здесь часто даёт именно сокращение ненужных срабатываний.
Архитектурная оптимизация требует смотреть на весь путь запроса: сколько шагов он проходит, сколько сервисов затрагивает и где появляются очереди, промежуточные записи, дополнительные вызовы и логи. Нередко проблема оказывается не в одной дорогой функции, а в том, что простое действие пользователя обрастает слишком длинной и затратной цепочкой.
Это можно сравнить с обычной покупкой йогуртов. Сами по себе они недорогие, и одна лишняя баночка ничего не меняет. Но если каждый раз брать чуть больше, чем реально нужно, не смотреть, что уже есть в холодильнике, и покупать “на всякий случай”, постепенно накапливается лишнее. Часть продуктов быстро съедается, часть залеживается, а часть в итоге просто выбрасывается. Формально каждая покупка кажется мелочью, но суммарно расходы растут уже не из-за реальной потребности, а из-за слабого контроля.
В этом и состоит логика FinOps: не запрещать расходы любой ценой, а делать их понятными, управляемыми и соразмерными нагрузке. В serverless экономия появляется не от отказа от модели, а от того, что команда осознанно убирает лишние операции и перестаёт проектировать “с запасом на всякий случай”.
Наблюдаемость затрат: алерты, бюджеты, теги и unit economics

Даже если архитектуру уже удалось сделать аккуратнее, одной оптимизации мало. Через месяц счёт может снова начать расти, если команда не видит, где именно появляются новые расходы. Поэтому следующий шаг — не только сокращать лишнее, но и выстраивать нормальную наблюдаемость затрат.
Это можно представить так:
| Инструмент | Зачем нужен | Что даёт на практике |
| Алерты | Сигнализируют о резких отклонениях и неожиданных всплесках расходов | Команда узнаёт о проблеме до того, как счёт успевает неприятно раздуться |
| Бюджеты | Задают финансовые рамки для сервиса, проекта или команды | Расходы перестают быть абстрактными и начинают соотноситься с лимитами |
| Теги | Помогают разложить затраты по сервисам, окружениям, продуктам и владельцам | Становится видно, кто и что именно генерирует в счёте |
| Unit economics | Показывают стоимость одного полезного действия: заказа, запроса, загрузки, обработки | Команда начинает смотреть не только на общий счёт, но и на цену конкретного бизнес-сценария |
Алерты помогают раньше замечать аномалии: резкий рост вызовов, логирования или потребления ресурсов по отдельным сценариям. Бюджеты задают рамки и делают разговор о расходах конкретнее: сервис или команда всё ещё в пределах нормы или уже выходит за неё. Теги добавляют структуру и позволяют разложить затраты по окружениям, продуктам, командам и сервисам. А unit economics связывает технические расходы с бизнес-действиями и показывает, сколько стоит одна регистрация, одна загрузка файла, один заказ или один пользовательский запрос.
Для serverless это особенно важно, потому что без нормальной видимости затрат счёт со временем всё равно начинает расползаться: через новые сценарии, рост нагрузки, лишние события или подорожавшие цепочки вызовов. Поэтому наблюдаемость нужна не как дополнение, а как способ удерживать результат оптимизации. Именно в такой связке расходы перестают быть сюрпризом и становятся управляемой частью архитектуры.
Заключение

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



