# Скрытые причины высокого счета AWS

> Разберите высокий счет AWS с помощью запросов к Cost and Usage Report, найдите десять видов потерь и устраните их без риска для систем.

У высокого счета AWS обычно несколько владельцев, даже если рост на первый взгляд объясняет одна строка. Видимый скачок может относиться к EC2, а причина скрываться за ним: развертывание удвоило межзональный трафик, неудачная загрузка оставила части файлов в S3 или изменение логирования многократно увеличило прием данных. Считайте счет реестром инженерных решений, а не одной суммой, которую надо оспорить.

Я начинаю с Cost and Usage Report (CUR) или его современного аналога Data Exports, который доставляется в S3 и анализируется через Athena. Включите идентификаторы ресурсов, почасовую детализацию, если она нужна для расследования, и теги распределения затрат. Здесь важна документация AWS Data Exports о строках отчета: `line_item_unblended_cost` содержит стоимость в строках использования, а кредиты, скидки, возвраты, налоги и эффекты обязательств имеют собственные типы строк. Если смешать их, ресурс будет выглядеть дешевле или дороже своего фактического потребления.

Сначала возьмите закрытый расчетный период, затем текущий месяц. Замените таблицу и даты ниже. Этот запрос строит реестр по сервисам и типам использования, с которым должны сходиться все последующие выводы.

```sql
SELECT
  line_item_product_code AS service,
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
HAVING SUM(line_item_unblended_cost) > 0
ORDER BY cost DESC;
```

Экспортируйте результат и храните его рядом со счетом. Если сумма не сходится с промежуточным итогом использования в счете, исправьте область охвата, плательщика, валюту или фильтр типов строк, прежде чем искать ресурсы. Из-за неверного знаменателя можно потерять неделю. Выполняйте каждый запрос по всем связанным аккаунтам и активным регионам. Регион, выбранный в консоли по умолчанию, часто создает ложное ощущение, что проблема исчезла.

## 1. Простаивающие и слишком крупные экземпляры EC2 продолжают тарифицироваться

Экземпляр EC2 не дешевеет оттого, что о нем никто не помнит. Серверы для разработки, оставленные на ночь, узлы замены, пережившие миграцию, и производственные экземпляры, рассчитанные на давно исчезнувший пик, создают нормальное использование, поэтому биллингу нечего отмечать как ошибку. Cost Explorer показывает расходы, а CloudWatch и Compute Optimizer дают данные о нагрузке, которые нужны до изменения размера или остановки.

Сначала ранжируйте ресурсы-экземпляры по стоимости. Идентификаторы ресурсов появляются, только если экспорт содержит детализацию на уровне ресурсов, а у некоторых общих начислений идентификатора все равно не будет.

```sql
SELECT
  line_item_resource_id AS instance_id,
  product_instance_type AS instance_type,
  line_item_availability_zone AS az,
  SUM(line_item_usage_amount) AS hours,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonEC2'
  AND line_item_usage_type LIKE '%BoxUsage%'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

Откройте самые дорогие экземпляры в CloudWatch и сравните как минимум две недели по загрузке процессора, сети, диска и памяти. EC2 не публикует данные о памяти гостевой системы без агента CloudWatch, поэтому один график с низкой загрузкой процессора не доказывает простой. Кэш базы данных, сервер лицензий или обработчик с большим потреблением памяти может почти не нагружать процессор, но все равно нуждаться в своем типоразмере. Рекомендации Compute Optimizer полезны как свидетельство, однако перед их применением проверьте окно наблюдения и ожидаемый пик.

Сначала настройте расписание там, где риск очевидно ниже, и только потом меняйте размер производственных систем. Останавливайте экземпляры, для которых допустим холодный запуск, удаляйте забытую емкость Auto Scaling, затем меняйте размер постоянных нагрузок. Ничего не завершайте, пока владелец не подтвердит путь к данным, замену и откат. Опаснее всего удалить экземпляр, оставив отдельный том EBS, цепочку снимков, IP-адрес и мониторинг.

## 2. Неподключенные тома EBS переживают свои экземпляры

EBS начисляет плату за выделенное хранилище, пока том находится в состоянии `available`. Это состояние означает, что том не подключен, но не означает, что он бесплатен, пуст или его безопасно удалять. Я видел, как тома после миграции лежали месяцами, потому что осторожный инженер сохранил их без даты удаления.

CUR показывает стоимость по идентификатору тома и типу использования. Группировка по типу использования разделяет gp2, gp3, выделенные IOPS, пропускную способность и другие оплачиваемые параметры.

```sql
SELECT
  line_item_resource_id AS volume_id,
  line_item_usage_type AS usage_type,
  SUM(line_item_usage_amount) AS quantity,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonEC2'
  AND (line_item_usage_type LIKE '%EBS:VolumeUsage%'
       OR line_item_usage_type LIKE '%EBS:VolumeP-IOPS%'
       OR line_item_usage_type LIKE '%EBS:VolumeP-Throughput%')
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2
ORDER BY cost DESC;
```

Сопоставьте эти идентификаторы с перечнем EC2 Volumes, отфильтрованным по состоянию `available` во всех регионах. Для каждого кандидата запишите время создания, теги, последнее подключение из CloudTrail, если история сохранилась, назначение файловой системы и владельца. Имя тома `old` ничего не доказывает. Создайте финальный снимок, если этого требуют условия восстановления, проверьте пригодность снимка для важных данных, затем удалите том.

Подключенное хранилище тоже тратит деньги. У тома gp3 могут быть отдельно выделены IOPS и пропускная способность намного выше наблюдаемого спроса. Том gp2 может оставаться слишком большим, потому что когда-то емкость покупали ради производительности. Проверьте `VolumeReadOps`, `VolumeWriteOps`, длину очереди, пропускную способность и поведение при исчерпании кредита. Меняйте по одному параметру, особенно для баз данных, чувствительных к задержке, и заранее запишите значение для отката.

## 3. Хранение снимков растет без очевидного виновника

Снимки EBS накапливаются незаметно, потому что счет показывает занятое хранилище, а операторы думают количеством снимков. Инкрементальный биллинг порождает опасное заблуждение: удаление одного старого снимка не обязательно освобождает объем, показанный в консоли, поскольку блоки, на которые ссылаются более новые снимки, остаются. AWS сам управляет этими ссылками при удалении снимка. Не пытайтесь вручную вывести порядок удаления из отображаемых полных размеров.

С помощью CUR ранжируйте расходы на снимки, затем сопоставьте их с перечнем снимков, образами AMI, правилами Recycle Bin и точками восстановления AWS Backup. Идентификаторы ресурсов заполнены не для всех начислений за снимки одинаково, поэтому первый запрос намеренно сохраняет тип использования и операцию.

```sql
SELECT
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  line_item_resource_id AS resource_id,
  SUM(line_item_usage_amount) AS gb_month,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonEC2'
  AND line_item_usage_type LIKE '%EBS:SnapshotUsage%'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

Обычная проблема начинается с двух систем хранения истории. Политика резервного копирования сохраняет ежедневные точки восстановления, а задача развертывания создает AMI и никогда не снимает их с регистрации. Инженер удаляет старые AMI, но оставляет их базовые снимки, либо удаляет план резервного копирования, не задав срок существующим точкам восстановления. Каждая система работает правильно, а вместе они хранят намного больше истории, чем требуется для восстановления.

Опишите хранение как договор о восстановлении: насколько далеко в прошлое бизнес должен уметь откатиться, как быстро и какие копии выполняют нормативные или клиентские требования. Затем назначьте одну ответственную систему для каждого набора данных. Перед удалением проверьте ссылки AMI, общий доступ, юридические запреты на удаление и межаккаунтные копии. Политики жизненного цикла не дадут возникнуть новой куче, но не решат неясность с владельцами уже накопленных данных.

## 4. Потери RDS скрываются в емкости, резервных узлах и сохраненном хранилище

Потери RDS редко сводятся к слишком крупному экземпляру. Топология Multi-AZ, тип хранилища, выделенные IOPS, срок резервного хранения, ручные снимки, реплики чтения, Extended Support и передача данных могут продолжать работать после изменения нагрузки. Базе данных с низкой средней загрузкой процессора все еще могут требоваться память, соединения, ввод-вывод или резерв для переключения, поэтому менять размер по одному графику безрассудно.

Начните с разбивки счета, в которой видны вариант развертывания и тип использования.

```sql
SELECT
  line_item_resource_id AS database_resource,
  product_database_engine AS engine,
  product_deployment_option AS deployment,
  line_item_usage_type AS usage_type,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonRDS'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3, 4
ORDER BY cost DESC;
```

Для дорогих экземпляров проверьте процессор, свободную память, соединения с базой, задержку чтения и записи, IOPS, пропускную способность, глубину очереди, отставание реплик и требования к переключению за репрезентативный деловой цикл. Performance Insights поможет понять, не создают ли давление SQL-запросы или ожидания, которые более крупный класс лишь маскирует. Изменение размера, после которого база упирается в задержку хранилища или своп, экономией не считается.

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

## 5. NAT-шлюзы превращают внутренние архитектурные решения в тарифицируемый трафик

У начислений за NAT gateway есть две части, которые команды часто смешивают: часы работы шлюза и обработанные байты. Удаление одного простаивающего шлюза сокращает часы, а маршрутизация интенсивного трафика к сервисам AWS в обход NAT сокращает байты. Счет может резко вырасти при неизменном EC2, потому что изменились загрузка образов контейнеров, скачивание артефактов, отправка телеметрии или межзональный маршрут.

Этот запрос разделяет почасовое использование и обработку данных. В названиях типов использования AWS есть региональные префиксы, поэтому ищите по стабильным окончаниям.

```sql
SELECT
  line_item_usage_type AS usage_type,
  line_item_resource_id AS nat_resource,
  line_item_availability_zone AS az,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonEC2'
  AND (line_item_usage_type LIKE '%NatGateway-Hours'
       OR line_item_usage_type LIKE '%NatGateway-Bytes')
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

В пространстве имен CloudWatch `AWS/NATGateway` есть метрики `BytesInFromSource`, `BytesOutToDestination`, `BytesInFromDestination` и `BytesOutToSource`. AWS рекомендует статистику `Sum` для этих байтовых метрик. По интервалу скачка выберите шлюз, затем найдите самые крупные пары адресов в VPC Flow Logs. Запрос Logs Insights может ранжировать разрешенные потоки, хотя точные поля зависят от настроенного формата журналов потоков.

```text
fields srcAddr, dstAddr, bytes, action
| filter action = "ACCEPT"
| stats sum(bytes) as transferred by srcAddr, dstAddr
| sort transferred desc
| limit 50
```

Не централизуйте NAT между зонами доступности только ради сокращения часов работы шлюзов, пока не оцените передачу данных и влияние на отказоустойчивость. Для интенсивного трафика к поддерживаемым сервисам AWS сравните gateway endpoints или interface endpoints с расходами на обработку NAT, часами работы конечных точек, передачей через них, поведением DNS и операционной сложностью. Более дешевый вариант зависит от объема и топологии. Измеряйте его по данным потоков, а не повторяйте правило из чужой архитектуры.

## 6. Межзональная и межрегиональная передача может стоить дороже связанного ею вычисления

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

Типы использования CUR содержат обозначения вроде `DataTransfer`, `DataXfer`, `Regional-Bytes`, `In-Bytes` и `Out-Bytes` в зависимости от сервиса и маршрута. Не считайте, что одного написания хватит для всего аккаунта. Сначала найдите фактические обозначения в счете.

```sql
SELECT
  line_item_product_code AS service,
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  product_from_location AS from_location,
  product_to_location AS to_location,
  SUM(line_item_usage_amount) AS gb,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND (lower(line_item_usage_type) LIKE '%transfer%'
       OR lower(line_item_usage_type) LIKE '%dataxfer%'
       OR lower(line_item_usage_type) LIKE '%regional-bytes%'
       OR lower(line_item_usage_type) LIKE '%out-bytes%')
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3, 4, 5
ORDER BY cost DESC;
```

Здесь теги часто бесполезны, поскольку начисление не всегда аккуратно относится к одному тегированному ресурсу. Соедините данные биллинга с метриками балансировщика, соединениями базы данных, телеметрией приложения и VPC Flow Logs за тот же час. Сравните день до развертывания и день после него. Если объем байтов вырос, а запросы нет, ищите повторные попытки, проверки работоспособности, репликацию, сжатие и слишком разговорчивые протоколы.

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

## 7. В счетах S3 прячутся старые версии, мелкие запросы и незавершенные загрузки

Потери S3 скрываются за репутацией дешевого хранения гигабайта. Бакеты с версионированием сохраняют неактуальные объекты, переходы жизненного цикла дают эффекты минимального срока хранения или запросов, миллионы мелких объектов увеличивают расходы на запросы и метаданные, а незавершенные многочастные загрузки хранят загруженные части до завершения или отмены. Документация AWS по многочастным загрузкам S3 прямо говорит, что эти части остаются платными. Поэтому очистку нужно задавать политикой жизненного цикла, а не ежеквартальным напоминанием.

Перед сменой классов хранения разбейте расходы S3 по типу использования и операции.

```sql
SELECT
  line_item_resource_id AS resource_id,
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonS3'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

CUR может не связать каждое начисление S3 с конкретным бакетом. Используйте S3 Storage Lens, чтобы найти крупные бакеты, байты неактуальных версий, маркеры удаления, холодные данные и незавершенные загрузки. Метрика `IncompleteMultipartUploadStorageBytes` измеряет объем входящих в область частей, а метрика частей старше семи дней помогает отделить брошенные загрузки от текущей работы. Метрики Storage Lens обновляются раз в день, поэтому сами по себе они не объяснят почасовой скачок запросов.

Настраивайте правила жизненного цикла на основе фактов о доступе и восстановлении. Удаляйте неактуальные версии, только если это допускают требования к откату и соответствию нормам. Прерывайте незавершенные многочастные загрузки через срок, который превышает длительность допустимой загрузки. Моделируйте переходы с учетом размера объекта, частоты доступа, стоимости извлечения, стоимости запросов и минимального срока хранения. Слепой перенос каждого объекта в самый холодный класс может заменить предсказуемый счет за хранение расходами на извлечение и операционной задержкой.

## 8. CloudWatch Logs берет плату за многословие и забывчивость

Потери CloudWatch Logs начинаются при приеме и продолжаются в сохраненных данных. Развертывание с отладкой может за ночь умножить число событий, а бессрочное хранение сохранит ошибку. Пользовательские метрики, измерения с высокой кардинальностью, подробный Container Insights и дублирующиеся маршруты логов создают отдельные расходы, поэтому итог сервиса нужно разбить по типу использования.

```sql
SELECT
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  line_item_resource_id AS resource_id,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code = 'AmazonCloudWatch'
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

В CloudWatch Logs ранжируйте группы логов по сохраненным байтам и проверьте настройки хранения. Затем по метрикам входящих байтов за интервал скачка найдите источники. Просмотрите выборку на предмет повторяющихся трассировок стека, строк проверок работоспособности в журналах доступа, слишком больших полей структурированных данных или одного исключения, записанного несколькими уровнями. Выборка должна сохранить данные для расследования сбоев, безопасности и аудита. Удаление всех отладочных сообщений после испуга от счета просто превращает расходы в более долгие сбои.

Задайте явный срок хранения для каждого класса логов. Шумной диагностике приложения подойдет короткий срок, если другая система хранит требуемую запись. Логи безопасности и аудита могут требовать намного большего срока. По возможности фильтруйте в источнике, ограничивайте размер данных исключения, не записывайте полные тела запросов и не позволяйте повторным попыткам фиксировать один сбой на каждом уровне. Настройка срока хранения сократит будущий объем. Удаление ненужных сообщений в источнике устраняет более крупную утечку.

## 9. Простаивающие балансировщики и публичные IPv4 кажутся слишком мелкими для проверки

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

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

```sql
SELECT
  line_item_product_code AS service,
  line_item_usage_type AS usage_type,
  line_item_resource_id AS resource_id,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND (line_item_product_code = 'AWSELB'
       OR lower(line_item_usage_type) LIKE '%publicipv4%')
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

Для каждого балансировщика проверьте обработанные байты, новые и активные соединения, число запросов, где оно доступно, состояние целей, слушатели, зависимости DNS и трафик хотя бы за один деловой цикл. Отсутствие здоровых целей не всегда означает, что ресурс не используется. Так может выглядеть сломанная производственная система. Для каждого публичного адреса проследите связанный сетевой интерфейс и систему, которая по-прежнему разрешается в этот адрес. IP Address Manager Public IP Insights помогает собрать сведения об использовании публичных IPv4 в разных регионах.

Удаляйте заброшенные стеки через их описание инфраструктуры, чтобы они не вернулись. Если у публичной точки есть настоящий потребитель, до удаления адреса проверьте, подходит ли ему общий вход, частное соединение или IPv6. Отдельная строка может выглядеть незначительно, но эта категория часто обнаруживает плохой жизненный цикл среды, из-за которого в других местах остаются более дорогие ресурсы.

## 10. Контейнеры и serverless переносят потери в резервы и параллелизм

Управляемые вычисления не устраняют простаивающую емкость, а меняют место ее появления. Задачи ECS могут запрашивать больше процессора и памяти, чем используют. Узлы EKS остаются недозаполненными, когда запросы ресурсов, daemon sets, ограничения топологии или параметры автомасштабирования мешают плотной упаковке. Lambda может сохранять выделенный параллелизм, который трафику больше не нужен. Задачи Fargate, работающие после опустошения очереди, по-прежнему тарифицируются по запрошенным ресурсам.

Первый запрос разделяет семейства вычислений и оплачиваемые параметры. Скорректируйте коды продуктов по значениям, которые фактически содержит базовый реестр.

```sql
SELECT
  line_item_product_code AS service,
  line_item_usage_type AS usage_type,
  line_item_operation AS operation,
  SUM(line_item_usage_amount) AS usage,
  SUM(line_item_unblended_cost) AS cost
FROM cur_database.cur_table
WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
  AND line_item_usage_start_date <  TIMESTAMP '2026-08-01'
  AND line_item_product_code IN ('AmazonECS', 'AmazonEKS', 'AWSLambda')
  AND line_item_line_item_type = 'Usage'
GROUP BY 1, 2, 3
ORDER BY cost DESC;
```

Для ECS и Fargate сравните резервы задачи с наблюдаемой загрузкой процессора и памяти, желаемое число задач с реальным спросом, а расписание сервиса с глубиной очереди или объемом запросов. Для EKS сравнивайте доступную емкость узла с запросами подов, а не только с текущей загрузкой. Кластер может показывать низкую загрузку процессора, хотя планировщик не способен разместить еще один под, потому что запросы памяти или правила топологии зарезервировали остаток. Учтите управляющую плоскость, балансировщики, тома, NAT-трафик и логи вокруг кластера. Их стоимость может превышать планируемое сокращение узлов.

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

## Сначала устраняйте переменные потери, потом договаривайтесь об обязательствах

Порядок исправлений должен зависеть от обратимости и доказательств, а не от размера самого заметного блока на панели. Сначала остановите появление новых потерь: отмените чрезмерное логирование, бесконечные повторные попытки, случайную репликацию или развертывание, изменившее сетевые пути. Затем удалите ресурсы с подтвержденным нулевым спросом, например брошенные загрузки, неподключенные тома после проверки восстановления, просроченные снимки и мертвые тестовые стеки. После этого составьте расписание непроизводственной емкости и измените размер вычислений, баз данных, контейнеров и выделенного параллелизма по репрезентативным метрикам. Потом меняйте архитектуру: конечные точки, маршрутизацию с учетом зон, жизненный цикл хранилища и общий вход. Лишь тогда моделируйте Savings Plans или Reservations по стабильной базе.

Сначала купить обязательство хочется потому, что консоль сразу показывает оценку скидки. При раздутой потерями базе это неправильный первый шаг. Обязательство может дать скидку на использование, которое следовало удалить, сократить гибкость во время миграции и создать видимость улучшения счета при неизменной небрежности потребления. Для решений об обязательствах используйте чистую амортизированную стоимость, а для понимания механизмов счета смотрите несмешанную стоимость использования и объемы. Это разные задачи.

### Докажите сокращение с помощью парных окон

Работу над расходами можно закрыть, только когда экспорт биллинга показывает ожидаемое изменение объема, а сервис сохраняет рабочие показатели. Сравнивайте одинаковые календарные интервалы с одним и тем же набором дней недели. Для расписания остановок сравнивайте часы экземпляров. Для NAT сравнивайте обработанные гигабайты. Для фильтрации логов сравнивайте принятые байты. Сравнение только денег может обмануть, если между окнами изменились курсы валют, многоуровневые цены, кредиты, налоги или распределение обязательств.

Этот запрос сравнивает два семидневных периода по сервису и типу использования. Он показывает стоимость и использование, поэтому мнимую экономию проще оспорить. Поставьте интервалы по обе стороны развертывания или очистки и исследуйте строки, где стоимость упала, а использование нет.

```sql
WITH measured AS (
  SELECT
    CASE
      WHEN line_item_usage_start_date >= TIMESTAMP '2026-07-01'
       AND line_item_usage_start_date <  TIMESTAMP '2026-07-08' THEN 'before'
      WHEN line_item_usage_start_date >= TIMESTAMP '2026-07-15'
       AND line_item_usage_start_date <  TIMESTAMP '2026-07-22' THEN 'after'
    END AS period,
    line_item_product_code AS service,
    line_item_usage_type AS usage_type,
    line_item_usage_amount AS usage,
    line_item_unblended_cost AS cost
  FROM cur_database.cur_table
  WHERE line_item_usage_start_date >= TIMESTAMP '2026-07-01'
    AND line_item_usage_start_date <  TIMESTAMP '2026-07-22'
    AND line_item_line_item_type = 'Usage'
)
SELECT
  service,
  usage_type,
  SUM(CASE WHEN period = 'before' THEN usage ELSE 0 END) AS usage_before,
  SUM(CASE WHEN period = 'after' THEN usage ELSE 0 END) AS usage_after,
  SUM(CASE WHEN period = 'before' THEN cost ELSE 0 END) AS cost_before,
  SUM(CASE WHEN period = 'after' THEN cost ELSE 0 END) AS cost_after
FROM measured
WHERE period IS NOT NULL
GROUP BY 1, 2
HAVING SUM(cost) > 0
ORDER BY cost_before - cost_after DESC;
```

Полнота тегов определяет возможную глубину атрибуции. Теги распределения затрат нужно активировать для биллинга, а новые теги не исправляют старые строки задним числом. Для общих ресурсов без тегов нужно правило распределения, понятное финансистам и инженерам, например по запросам, байтам, часам задач или фиксированной доле платформы. Не изображайте ложную точность. Если сетевые расходы нельзя распределить глубже общей платформы, оставьте их на ней и назначьте инженера, который изменит архитектуру или измерение.

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

Консолидированный биллинг требует еще одной проверки. Рост сервиса на уровне плательщика может возникнуть из-за нового связанного аккаунта, переноса ресурса между аккаунтами или изменения распределения скидки, а не из-за общего роста использования. Повторите главный запрос с `line_item_usage_account_id` в группировке, затем проверьте регионы внутри найденного аккаунта. Не исключайте песочницы и аккаунты приобретенных компаний, пока владельцы не подтвердят их закрытие. Пустая панель в основном производственном аккаунте ничего не говорит о ресурсах под забытым логином.

Ведите реестр находок с владельцем, аккаунтом, регионом, ресурсом, окном наблюдения, месячной стоимостью, зависимостью, действием, откатом и подтвержденным результатом. Помечайте оценки как оценки. После каждого изменения сравнивайте объем использования и стоимость с базой той же длины. Изменения цен, кредиты и распределение обязательств могут сдвинуть сумму, не доказывая снижения инженерного спроса.

Team & AI Audit от oleg.is может включать этот путь расходов, когда затраты на инфраструктуру переплетены со структурой команды и привычками разработки. Полезный результат одинаков независимо от того, нанимаете вы помощь или разбираетесь сами: у каждой крупной строки есть владелец, у каждого исключения есть срок, а следующий счет объясняется изменениями ресурсов до вопроса финансовой команды.
