Uses sample jaffle_shop fixtures (manifest.json + catalog.json + sample_diff.sql). Try int_order_items.

🚨
Critical risk — this PR should be blocked before merging
4 patterns detected · 5 models in impact set · approximate confidence
CRITICAL
$0.1379
baseline $/run
$0.1599
after merge $/run
+$0.0220
added per run
approximate
estimate confidence
$6.25/TiB
BQ on-demand rate
Cost breakdown — baseline vs after merge
Model Role Materialization Baseline $/run After merge $/run Δ / run Confidence
int_order_items
● changed incremental table $0.0012 $0.0232 +$0.0220 ↑ exact
rpt_customer_ltv
↓ downstream table $0.0427 $0.0427 exact
rpt_daily_revenue
↓ downstream table $0.0732 $0.0732 exact
rpt_cohort_analysis
↓ downstream table $0.0183 $0.0183 exact
fct_orders
↓ downstream incremental $0.0024 $0.0024 approximate
TOTAL $0.1379 $0.1599 +$0.0220 ↑ approximate
Estimates use catalog.json num_bytes stats. Incremental models are approximated at ~5% of stored bytes per run (actual depends on lookback window). Table/seed materializations scan the full stored size — these are exact. A live BigQuery dry-run (Team tier) provides exact bytes for incremental models.
Detected patterns — 4 found
critical Incremental → full-refresh switch INCREMENTAL_TO_FULL_REFRESH

Model materialization changed from incremental to table. Every pipeline run will now scan the entire table instead of only recent rows. This is the most common cause of 10–100× BigQuery bill spikes.

If you need to add columns, use materialized='incremental' with a schema migration. Only switch to table if a one-time full rebuild is intentional, then switch back.

critical Partition filter removed PARTITION_FILTER_DROPPED

The {% if is_incremental() %} WHERE clause that restricted scans to recent partitions was present in the base branch but removed in this PR. BigQuery will now scan all partitions on every run, which can multiply cost by 10–100×.

Restore the incremental WHERE guard with a date lookback window. If you need to backfill historical data, run dbt run --full-refresh once, then restore the filter.

high New join on `my-bq-project.raw.discounts` UNFILTERED_JOIN_INTRODUCED

A new JOIN on my-bq-project.raw.discounts was added in this PR. If this is a large table without a filter on the ON or WHERE clause, BigQuery will scan the full table on every run even if only a few rows match.

Add a partition filter or selective WHERE clause on my-bq-project.raw.discounts. If it is a small lookup table (≤1 GB), this pattern is low risk.

high Large-table downstream fan-out (4 models ≥1 GB) LARGE_TABLE_FAN_OUT

4 downstream model(s) — rpt_customer_ltv, rpt_daily_revenue, rpt_cohort_analysis, fct_orders — collectively hold 30.0 GB and will inherit the upstream change's full-scan cost on every pipeline run.

rpt_customer_ltv 7.0 GB
rpt_daily_revenue 12.0 GB
rpt_cohort_analysis 3.0 GB
fct_orders 8.0 GB

Check that each downstream incremental model has its own lookback filter. If any are table materializations they will re-scan from scratch every run.

GitHub PR comment — copy-ready markdown
Markdown · paste directly into a GitHub PR comment
## dbtGuard — BigQuery PR Cost Analysis 🚨 **+0.0220 USD/run** estimated cost change · 4 pattern(s) detected · overall severity **CRITICAL** ### Cost Impact — changed model + downstream | Model | Role | Baseline $/run | New $/run | Δ/run | Confidence | |-------|------|---------------|-----------|-------|------------| | `int_order_items` | ● changed | $0.001160 | $0.0232 | +$0.0220 ↑ | exact | | `rpt_customer_ltv` | ↓ downstream | $0.0427 | $0.0427 | $0.00 | exact | | `rpt_daily_revenue` | ↓ downstream | $0.0732 | $0.0732 | $0.00 | exact | | `rpt_cohort_analysis` | ↓ downstream | $0.0183 | $0.0183 | $0.00 | exact | | `fct_orders` | ↓ downstream | $0.002441 | $0.002441 | $0.00 | approximate | | **TOTAL** | | **$0.1379** | **$0.1599** | **+$0.0220 ↑** | approximate | > ⚠️ Estimates use catalog `num_bytes` stats. Incremental models are approximated at ~5% of stored bytes. Live dry-run (Team tier) gives exact bytes for incremental models. ### Detected Patterns #### 🚨 `CRITICAL` — Incremental → full-refresh switch Model materialization changed from `incremental` to `table`. Every pipeline run will now scan the entire table instead of only recent rows. This is the most common cause of 10–100× BigQuery bill spikes. **Recommendation:** If you need to add columns, use `materialized='incremental'` with a schema migration. Only switch to `table` if a one-time full rebuild is intentional, then switch back. #### 🚨 `CRITICAL` — Partition filter removed The `{% if is_incremental() %}` WHERE clause that restricted scans to recent partitions was present in the base branch but removed in this PR. BigQuery will now scan all partitions on every run, which can multiply cost by 10–100×. **Recommendation:** Restore the incremental WHERE guard with a date lookback window. If you need to backfill historical data, run `dbt run --full-refresh` once, then restore the filter. #### ⚠️ `HIGH` — New join on `my-bq-project.raw.discounts` A new JOIN on `my-bq-project.raw.discounts` was added in this PR. If this is a large table without a filter on the ON or WHERE clause, BigQuery will scan the full table on every run even if only a few rows match. **Recommendation:** Add a partition filter or selective WHERE clause on `my-bq-project.raw.discounts`. If it is a small lookup table (≤1 GB), this pattern is low risk. #### ⚠️ `HIGH` — Large-table downstream fan-out (4 models ≥1 GB) 4 downstream model(s) — `rpt_customer_ltv`, `rpt_daily_revenue`, `rpt_cohort_analysis`, `fct_orders` — collectively hold 30.0 GB and will inherit the upstream change's full-scan cost on every pipeline run. **Affected downstream models:** `rpt_customer_ltv`, `rpt_daily_revenue`, `rpt_cohort_analysis`, `fct_orders` **Recommendation:** Check that each downstream incremental model has its own lookback filter. If any are `table` materializations they will re-scan from scratch every run. --- _[dbtGuard](https://dbtguard.dev) · BigQuery on-demand rate: $6.25/TiB · confidence: approximate_