# Debug a dbt model by profiling each CTE

> Debug a dbt model in one click. Profile CTEs shows the runtime and row count of every CTE, so the join that inflates your rows stands out.

Source: https://altimate.ai/product-highlights/debug-a-dbt-model-by-profiling-each-cte

[.md](https://altimate.ai/product-highlights/debug-a-dbt-model-by-profiling-each-cte.md) 

Copy as MD

PowerUser Plugin for dbt

## Profile Every CTE in a dbt Model to Find the Join That Inflates Your Rows

Debug a dbt model in one click. Profile CTEs shows the runtime and row count of every CTE, so the join that inflates your rows stands out.

Atharva ShahOct 16, 20263 min read

 Profile every CTE in a dbt model to find the join that inflates your rows 

TL;DR

-   **What it is.** One-click buttons in the PowerUser Plugin for dbt. Five sit above every dbt model. Execute CTE and Profile CTEs sit above each CTE.
-   **Who it is for.** Analytics engineers handed a ticket on a model they did not write, or a dashboard that broke after a change.
-   **What you get.** The runtime and row count of every CTE in one click, so a join that multiplies rows stands out from the rest.

A dashboard shows duplicate rows and inflated totals after a recent change. The model compiles and the tests pass. To debug a dbt model like this by hand, you pull each CTE out of the Jinja and run it alone, in order. Then you compare row counts yourself. On a long model, that takes hours.

## Run One CTE Without Pulling It Out of the Jinja

Click **Execute CTE** above any CTE. The extension compiles the Jinja, runs the CTEs that one depends on, and shows the output of that CTE alone. You check a change to one CTE without running the whole model. After a fix, run that CTE again and compare its row count with the number you expected. The [CTE preview guide](https://help.altimate.ai/dbt-power-user/test/runctes/) covers the same flow from the docs.

 The orders.sql editor with the model code lens Execute Query, Explain, Optimize, Document and Review above line 1, and the CTE code lens Execute CTE: orders and Profile CTEs above the first CTE. 

## Profile Every CTE to Spot the One Out of Line

Click **Profile CTEs**. The extension runs every CTE one by one and writes its runtime and row count beside it. In the demo, `orders` took 4.4 seconds for 99 rows. The `payments` CTE took 644 ms for 113 rows, and `order_payments` took 181 ms for 99 rows.

 Profile CTEs results in orders.sql. The orders CTE reads 4.4s and 99 rows, payments reads 644ms and 113 rows, and order\_payments reads 181ms and 99 rows. 

Now suppose someone changed a left join in this model to a full outer join. In the presenter's example, one CTE jumps from about 99 rows to about 990 and runs for about 10 seconds. Every other CTE in the model stays near 100 rows. That one CTE holds the bad join, and you found it in a single click. As a rule, compare each CTE with the CTE before it. A CTE that returns more rows than its inputs, right after a join, is the first place to look.

Spotlight 4 video, debug dbt models and profile CTEs in one click

## Explain or Optimize the Model Without Writing a Prompt

The model row holds four more buttons. Each one opens an Altimate Code session with the prompt already written:

-   **Explain** walks through the model step by step, Jinja variables included, and flags anything worth a second look.
-   **Optimize** returns ways to make the model faster or cheaper.
-   **Document** writes the model docs in place.
-   **Review** checks the code changes you made.

 The Explain: orders.sql and Optimize: orders.sql chat tabs. The explanation lists the final select, the resulting output columns and a section titled Why use Jinja loops here. 

The [Explain guide](https://help.altimate.ai/dbt-power-user/develop/explanation/) lists every way to start an explanation.

### Install the dbt VS Code extension

[Install from Marketplace](https://marketplace.visualstudio.com/items?itemName=innoverio.vscode-dbt-power-user) [Book a 30-min demo →](https://calendly.com/d/ctnv-rbc-yr3/altimate-ai-overview) [Read the docs →](https://help.altimate.ai/dbt-power-user/) 

## Frequently Asked Questions

Where do the one-click buttons appear?

A code lens row sits above the first line of every dbt model. It holds Execute Query, Explain, Optimize, Document and Review. A second row above each CTE shows Execute CTE and Profile CTEs.

What does Profile CTEs measure?

It runs each CTE in the model one at a time. It writes the runtime and the row count beside each CTE. A CTE whose row count or runtime is far out of line with its neighbors is the first place to look.

How do I find a fan-out join in a dbt model?

Profile the CTEs and compare row counts. A join that matches more rows than you expect multiplies the output, so one CTE returns far more rows than the CTE before it. In the demo, a full outer join that replaced a left join turned about 99 rows into about 990.

What is the difference between Execute Query and Execute CTE?

Execute Query runs the whole model and shows its result. Execute CTE runs one CTE and the CTEs it depends on, and shows only that CTE's output. The extension compiles the Jinja in both cases.

Do Explain and Optimize change my code?

No. Both open an Altimate Code chat and return text, such as an explanation or a list of suggested changes. You decide what to apply to your model. You can keep asking questions in the same session.

Do these buttons need an API key?

Executing a query or a CTE works in the free extension. Explain, Optimize and the other Altimate Code actions need a free Altimate API key. They also need the Datamates extension, which installs with the PowerUser Plugin for dbt.

Does this work in Cursor?

Yes. The PowerUser Plugin for dbt installs in Cursor from Open VSX. The same code lens buttons appear above every model and every CTE, and Profile CTEs works the same way as in VS Code.

On this page

-   Run One CTE Without Pulling It Out of the Jinja 
-   Profile Every CTE to Spot the One Out of Line 
-   Explain or Optimize the Model Without Writing a Prompt 

## Related Resources

PowerUser Plugin for dbt Profile a dbt Query in One Click and Get Its Bugs, Anti-Patterns and Fixes Ranked

https://altimate.ai/product-highlights/profile-a-slow-dbt-query-execution-plan

PowerUser Plugin for dbt Ask Altimate Code About a dbt Model Straight from the Lineage Graph

https://altimate.ai/product-highlights/ask-ai-about-dbt-lineage-in-vs-code

PowerUser Plugin for dbt Hover Over a dbt Model Reference or Macro to See Its Depth and Who Uses It

https://altimate.ai/product-highlights/dbt-macros-and-ref-explained-on-hover

Help Doc Generate and Edit Tests

https://help.altimate.ai/dbt-power-user/test/writetests/

## Install the dbt VS Code Extension. Free to Start.

Power User for dbt is an open source VS Code extension that adds column lineage, autocomplete, AI docs, query previews and health checks to your dbt project.

[Install from Marketplace](https://marketplace.visualstudio.com/items?itemName=innoverio.vscode-dbt-power-user) [Book a Demo](https://calendly.com/d/ctnv-rbc-yr3/altimate-ai-overview) 

[Read the docs →](https://help.altimate.ai/dbt-power-user/) 

 The Altimate platform: team spend by warehouse, dbt column lineage and an Altimate Code session recap
