Learning Platform
Глоссарий Troubleshooting
Урок 16.04 · 22 мин
Средний
dbt-cloudcost-insightssnowflakebigqueryoptimizationfinops

Cloud Cost Insights

Cost Insights — компонент Cloud / Studio, который связывает warehouse-расходы с конкретными dbt-моделями и Jobs. Это FinOps-инструмент: вместо абстрактного “Snowflake stoit 30k/month"—конкретное"модельfctordershistoryстоит30k/month" — конкретное "модель `fct_orders_history` стоит 4k/month и её можно оптимизировать”.

dbt-iii: Performance at Scale — глубокий разбор стоимости materializations

В 2026 году, после merger c Fivetran, Cost Insights также покрывает Fivetran-стоимости в Enterprise-тарифе. Этот урок — про dbt-часть.


Зачем атрибуция расходов

Без атрибуции отдел data smotрит на Snowflake bill в 30kинезнает,какегоуменьшить.Всемодели"вместе"стоят30k и не знает, как его уменьшить. Все модели "вместе" стоят 30k, но точечно нет понимания, где tradeoff.

С атрибуцией:

  • Модель X стоит $4k/month — анализируем, может ли быть incremental вместо table
  • Модель Y стоит $1.5k и запускается 4 раза в день — может, можно реже?
  • 80% расходов идёт на 10 моделей (Парето) — фокусируем optimization там

Это превращает FinOps из “уменьшить bill в принципе” в “оптимизируй конкретные 10 моделей”.


Как работает Cost Insights технически

Cloud собирает данные о warehouse-usage через две точки:

Cost Insights: data flow
dbt JobProduction deploy job в Cloud запускает dbt-команды на warehouse
SQL queries с tagged context
WarehouseSnowflake QUERY_HISTORY / BigQuery INFORMATION_SCHEMA.JOBS_BY_PROJECT хранят историю запросов с execution metrics
Cloud collectorService Cloud периодически (часто раз в час) запрашивает warehouse query history через credentials environment'а
Attribution engineСвязывает каждый query с dbt-моделью через QUERY_TAG (Snowflake) или labels (BigQuery), которые dbt автоматически проставляет
Cost Insights UIДашборд: per-model cost, per-job cost, per-day тренды, top expensive models

Snowflake: через QUERY_TAG

В Snowflake dbt автоматически проставляет QUERY_TAG для каждого запроса. Формат:

{
  "app": "dbt",
  "dbt_version": "1.10.21",
  "project_name": "ecommerce",
  "target_name": "prod",
  "node_id": "model.ecommerce.fct_orders",
  "node_name": "fct_orders",
  "node_alias": "fct_orders",
  "node_package_name": "ecommerce",
  "node_original_file_path": "models/marts/fct_orders.sql",
  "node_database": "ANALYTICS",
  "node_schema": "MARTS",
  "node_materialized": "table",
  "node_meta": {...},
  "run_started_at": "2026-05-19T06:00:00Z",
  "invocation_id": "abc-123-xyz"
}

Cloud собирает QUERY_HISTORY join’ит с этим query_tag и получает per-model costs:

-- Упрощённый запрос Cost Insights
SELECT
  QUERY_TAG:node_id::string AS model_id,
  SUM(CREDITS_USED_CLOUD_SERVICES + CREDITS_USED) AS total_credits,
  COUNT(*) AS query_count,
  AVG(TOTAL_ELAPSED_TIME) AS avg_duration_ms
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE QUERY_TAG:app::string = 'dbt'
  AND START_TIME >= DATEADD(DAY, -7, CURRENT_DATE)
GROUP BY 1
ORDER BY total_credits DESC;

Cloud берёт credits, умножает на cost-per-credit (стандартный rate 2.502.50-4.00 для most accounts) и показывает в долларах.

BigQuery: через labels

В BigQuery dbt проставляет labels:

dbt_invocation_id: abc-123
dbt_node_id: model_ecommerce_fct_orders
dbt_project: ecommerce
dbt_target: prod

Cloud join’ит INFORMATION_SCHEMA.JOBS_BY_PROJECT (или JOBS_BY_ORGANIZATION для billing-уровня) с labels:

SELECT
  labels.value AS model_id,
  SUM(total_slot_ms) / (1000 * 60 * 60) AS slot_hours,
  SUM(total_bytes_billed) / POWER(10, 12) AS tib_billed,
  COUNT(*) AS query_count
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
   , UNNEST(labels) AS labels
WHERE labels.key = 'dbt_node_id'
  AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY 1
ORDER BY slot_hours DESC;

BigQuery cost model — flat-rate (per-slot) или on-demand (per-TB). Cloud делит по обоим, показывает в долларах.

Другие warehouses

  • Redshift / Databricks — поддержка частичная, требует Enterprise tier и специфичной конфигурации.
  • Postgres — не поддерживается (warehouse-без-credits модель).
  • DuckDB — не поддерживается в Cloud, потому что Cloud в принципе не работает с DuckDB.

Что показывает Cost Insights UI

Дашборд имеет несколько разделов:

Top expensive models

Ranked list моделей по cost за выбранный период (7d / 30d / 90d / custom). Колонки:

  • Model name
  • Total cost ($)
  • Run count
  • Avg cost per run ($)
  • Trend (рост / стабильно / падение)

Это первое, что вы смотрите при FinOps-обзоре. Парето обычно работает: топ-10 моделей = 60-80% от всех затрат.

Cost per Job

То же самое, но в разрезе Jobs. Полезно, чтобы понять, какой job самый дорогой:

  • Daily prod deploy: $1200/week
  • Hourly partial refresh: $800/week
  • CI jobs: $200/week
  • Ad-hoc runs: $50/week

Часто оказывается, что CI jobs дороже, чем интуитивно ожидается — потому что они запускаются часто.

График cost per day за выбранный период. Видны:

  • Регулярные паттерны (выше будни / ниже weekends)
  • Спайки (тот день, когда кто-то запустил dbt build --full-refresh)
  • Тренды (рост на 10% в неделю — данные растут вместе с бизнесом)

Спайки требуют расследования: что произошло, и кто запустил, и не повторится ли.

Per-environment breakdown

Разбивка по environment:

  • Production: основной cost
  • CI: cost от PR-валидаций
  • Staging: pre-prod testing
  • Development: dev-experimentation

Часто CI cost оказывается 15-30% от prod cost — это significant и optimizable.


Как использовать для optimization: practical playbook

Cost Insights не оптимизирует за вас — даёт visibility. Что делать с visibility:

Step 1: identify top 10 expensive models

Открываете Cost Insights -> Top expensive models -> 30d period. Записываете список топ-10.

Типичный результат для команды на Snowflake:

  1. fct_orders_history — $4200/month
  2. mart_customer_360 — $2800/month
  3. int_events_enriched2100/month...ещё7моделейдо2100/month ... ещё 7 моделей до 500/month
  • Tail: 80 моделей суммарно $3000/month

Парето на лицо: top 3 = 50% бюджета.

Step 2: классифицировать причины

Для каждой топ-модели смотрите:

  • Materialization: table / incremental / view?
  • Run frequency: сколько раз в день/неделю?
  • Rows processed: миллионы / миллиарды?
  • Recent execution time trend: растёт ли?

Категории проблем:

A. Full table rebuild каждый раз. Модель materialized='table' пересчитывается полностью, хотя данные incremental. Fix: переключить на incremental со стратегией insert_overwrite или merge.

B. Too frequent. Модель mart_customer_360 строится каждый час, но downstream BI обновляется раз в день. Fix: уменьшить частоту до раз в день.

C. Wide scan. fct_orders_history сканирует всю историю каждый run, потому что нет clustering / partitioning. Fix: добавить cluster_by / partition в config, добавить incremental_predicates для prune’инга.

D. Expensive join. Модель делает CROSS JOIN или join без proper keys. Fix: переписать SQL, добавить broadcast hint, использовать microbatch.

E. Dependency: cheap upstream rebuild. Сама модель дешёвая, но триггерит rebuild дорогих upstream. Fix: использовать state:modified+1 или state:n_plus 1 чтобы избежать вертикальной перезаписи.

Step 3: prioritize wins

Сортируете кандидатов по estimated win × effort. Часто оптимальные wins:

OptimizationEffortEstimated win
Table -> incremental на 1 модели2-4 часа1k1k-3k/month
Reduce frequency 4 -> 1 раз в день0.5 часа200200-500/month
Add cluster_by на large table1 час30-50% query reduction
Move CI to defer + state:modified+1-2 дня (если ещё не сделано)300300-800/month
Disable source freshness в CI0.5 часа5050-100/month

Делаете 3-5 wins за спринт. Через месяц — Cost Insights показывает падение на 30-50%.

Step 4: monitor regression

После optimization включаете regression monitoring: алерт, если total cost растёт быстрее, чем data volume. Cloud Enterprise может сделать через AnomalyDetection в Notifications.


Типичные находки на реальных проектах

Из опыта аудитов dbt-проектов после внедрения Cost Insights:

1. “Snapshot in dev” trap. Команда забыла настроить target.name == 'prod' гард на snapshots. Каждый dev-run пересчитывал snapshots в dev. Cost: $800/month избыточно.

2. Тесты дороже моделей. На широких таблицах unique тест на колонку без index’а делает full table scan. Cost тестов был 40% от cost моделей. Fix: severity = warn для not-critical + индексы / cluster_by.

3. CI без defer и state:modified. Каждый CI job запускал dbt build всего проекта. На команде из 5 dev’ов и 200 моделей это 1500/monthсверху.SlimCIснизилдо1500/month сверху. Slim CI снизил до 200.

4. Source freshness в каждом step deploy. dbt source freshness запускался первым шагом в каждом из 12 daily jobs. Cost — $300/month избыточно. Достаточно одного раза в день.

5. Full refresh on Mondays. Кто-то добавил cron-job, который запускает dbt run --full-refresh каждый понедельник “для cleanup”. Cost — $4k/month на одной модели. Удалили cron — никто не заметил.

6. Materialized view с rebuild на каждый source change. Modern data stack feature — materialized views на dbt (через materialized='materialized_view'). На Snowflake / BigQuery MV пересоздаётся automatically при изменениях. Если source с миллионами updates per day — MV перестраивается чаще чем нужно. Cost: $2k+/month.


Cost Insights в Core: что доступно

Без Cloud вы можете построить эквивалент сами:

  1. Snowflake: запросы к SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY с фильтром на QUERY_TAG. Соберите данные в отдельную dbt-модель (мета-модель). dbt-snowflake adapter автоматически проставляет query_tag, вам надо только парсить его.

  2. BigQuery: запросы к INFORMATION_SCHEMA.JOBS_BY_PROJECT с join’ом по labels. Аналогично.

  3. dbt_artifacts package (от Brooklyn Data Co): парсит run_results.json в таблицы, дополняет warehouse-метриками. Это open-source аналог Cost Insights.

  4. Elementary package: data observability tool, есть free и paid-tier (Elementary Cloud). Включает cost tracking как opt-in.

Cloud Cost Insights — это удобная UI-обёртка над тем, что технически доступно в любом warehouse. Если у вас Core и есть инженерный ресурс — построить эквивалент за 1-2 спринта вполне реально.


Что middle-инженер должен уметь

  1. Объяснить, как Cost Insights технически связывает warehouse query history с dbt-моделями (QUERY_TAG в Snowflake, labels в BigQuery).
  2. Найти топ-10 expensive models в проекте и классифицировать причины (full rebuild / too frequent / wide scan / expensive join / dependency).
  3. Спроектировать optimization plan: 3-5 wins с оценкой effort и payoff.
  4. Знать про эквивалент через open-source (dbt_artifacts package, прямые запросы к QUERY_HISTORY).
  5. Понимать, что typical wins — это переход table -> incremental, reduction frequency, cluster_by / partitioning, Slim CI с defer.

Попробуй сам

Если у вас Snowflake (с правами на ACCOUNT_USAGE) — запустите следующий запрос:

SELECT
  PARSE_JSON(QUERY_TAG):node_name::string AS model_name,
  SUM(CREDITS_USED_CLOUD_SERVICES + CREDITS_USED) AS total_credits,
  COUNT(*) AS run_count,
  AVG(TOTAL_ELAPSED_TIME) / 1000 AS avg_duration_seconds
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY
WHERE QUERY_TAG ILIKE '%"app":"dbt"%'
  AND START_TIME >= DATEADD(DAY, -7, CURRENT_DATE)
GROUP BY 1
ORDER BY total_credits DESC
LIMIT 10;

Это покажет, какие модели стоят больше всего. Для BigQuery аналогичный запрос на JOBS_BY_PROJECT.

Если warehouse — Postgres / DuckDB — Cost Insights не применим (нет credit-модели). Но можно собрать stats по execution time через pg_stat_statements (Postgres) или system tables (DuckDB) и аппроксимировать.


Проверка знанийKnowledge check
Команда смотрит на Cost Insights и видит: один Job 'Hourly partial refresh' стоит $800/неделю, что больше, чем daily prod-deploy ($600/неделю). При этом downstream-dashboards обновляются раз в день. Что не так и как оптимизировать?
ОтветAnswer
Проблема — частота не соответствует downstream-потреблению. Hourly partial refresh запускается 168 раз в неделю, тратит $800. Но downstream BI обновляется раз в день, то есть из 168 запусков реально нужны 7 (раз в день). Остальные 161 запусков работают впустую — данные пересчитаны, но никем не прочитаны до следующего дня. Анализ: (1) Зачем кому-то понадобилась hourly? Возможно, исторически — был интрадей-dashboard, который потом убрали. (2) Какие downstream системы реально читают эти данные? Через exposures / lineage можно увидеть. Оптимизация: (1) Сначала проверить consumers — реально ли никто не читает hourly. (2) Если так — снизить до daily, экономия ~85% от $800 = $680/неделю = $2700/month. (3) Если есть один consumer, который требует hourly — обсудить, можно ли его перевести на 3x daily (раз в 8 часов) — экономия 50%. (4) Альтернатива: оставить hourly, но переключить модель на microbatch incremental — каждый run обрабатывает только новый час данных, что в 24 раза быстрее и дешевле. Главный урок: Cost Insights даёт visibility, но решение требует business context — кто потребляет данные и с какой частотой.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 6. Как технически работает Cost Insights в Cloud для Snowflake? Какая ключевая metadata позволяет связывать warehouse query с конкретной dbt-моделью?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5