CertSafari
    DBT Architect· Lessons

    Domain 8 · Lesson 38/39

    dbt Catalog for lineage, troubleshooting and cost optimisation

    Using dbt Catalog to understand the current lineage, troubleshoot issues and optimise cost and performance

    16 min read
    2.56% of exam
    6 sources
    Published 13 Oct 2026
    Docs as of 12 Oct 2026

    What you will be able to do

    • Explain which job runs feed dbt Catalog, and why a model can be missing from it or vanish from it
    • Use the lineage graph, selectors and column-level lineage to trace where a breakage started and what it affects
    • Read data health signals to tell a Caution resource from a Degraded one
    • Use Model performance and Cost Insights to find slow, failing or expensive models and judge what the cost figures mean

    Key concept

    Catalog reflects deployed state — Catalog shows only what production or staging job runs have reported through the Discovery API. You read lineage, health, performance and cost there, so an environment that has not run, or a model that has not been built there, does not show up.

    1.Where Catalog's picture of a project comes from

    dbt Catalog is where you go to see the lineage, health and cost of a dbt project. It only shows what deployment job runs have reported. Catalog reads metadata from the Discovery API for the environment you have designated as production or staging. After each job run in that environment, it picks up the new metadata automatically, and that includes deploy jobs and merge jobs. Setting up a job to produce this documentation is covered in [generating documentation on a job](lesson:4.7). On dbt v2, jobs refresh catalog metadata on every run without a separate dbt docs generate step.

    CI jobs never update Catalog. They test proposed changes rather than the production state, so they don't provide the metadata Catalog needs. A new model that has only passed CI won't appear in Catalog. It shows up after the next production or staging run that includes it.

    Two conditions decide whether a model gets metadata at all. First, the model must exist in the manifest. Second, it must appear in the run_results of a dbt build, dbt run or dbt clone. It doesn't matter whether that run succeeded or failed. Because a failed build still counts, Catalog can show you the failure in context instead of hiding the model.

    Metadata also disappears in two ways. If you delete a model from the project, its metadata goes after the next job run that no longer includes it. If an environment has no job runs for three months, all metadata for that environment is purged. For example, a staging environment that only runs before quarterly releases can turn up empty. Scheduling at least one job every three months prevents this.

    What a job must run for each kind of Catalog metadata to appear
    To see in CatalogThe job must run
    All metadatadbt build and dbt source freshness together in the same job
    Model lineage, details, or resultsdbt run or dbt build on that model
    Columns and statisticsAny job run in the environment
    Data test resultsdbt test or dbt build
    Source freshness resultsdbt source freshness
    Snapshot detailsdbt snapshot or dbt build

    Checkpoint 1 of 8· Check yourself

    An engineer opens a PR that adds fct_refunds. The CI job builds it successfully, but fct_refunds is not in Catalog. What explains this?

    Sources1

    2.Reading the lineage graph to trace cause and impact

    The lineage graph is an interactive version of the project's DAG. By default it shows applied state: models that have been built successfully and are available to query, not every model defined in code. This matters when you're troubleshooting. A model that is missing from the graph has not been built in that environment, even if it is in your branch.

    To open the full graph, select Overview in the left sidebar and click Explore Lineage. If nothing appears, click Render Lineage. Very large projects may not render at all. In that case, select a subset of nodes with selectors instead of loading the whole DAG. Nodes are colour-coded and have icons by resource type. Tests and macros are left out of the full graph unless a search returns them, so you see their lineage on their own resource details pages.

    For troubleshooting, the right-click menu is the main tool. You can refocus on a node with both directions, with downstream nodes only, or with upstream nodes only. When a model fails, refocus upstream to look for the cause and downstream to see what is affected. Selecting a node opens a side panel. Its General tab shows the description and materialization, and it has buttons to view the resource details, open the model in the Studio IDE, or copy a link to share.

    The search bar takes the same selectors and graph operators you use on the command line. +orders returns everything upstream of orders. +dim_customers,resource_type:source returns only the sources upstream of dim_customers. You can also use --select and --exclude. Selectors that need a state comparison are not available, which means result, source status and state. To find what changed, use the Latest updates view, not a state selector.

    Checkpoint 2 of 8· Check yourself

    Which of these will NOT work in the Catalog search bar?

    Checkpoint 3 of 8· Exam question

    In dbt Catalog, an analyst reviewing project_b's lineage graph sees that model downstream_c directly references the public model upstream_b from project_a. Model upstream_b itself depends on another public model, upstream_a, that also lives in project_a. The analyst reports that upstream_a is missing from downstream_c's lineage graph in Catalog, even though the Studio IDE lineage view shows both upstream_b and upstream_a. What explains this difference?

    Sources1

    3.Column-level lineage for pinpointing breakages

    Model-level lineage shows which models depend on each other. Column-level lineage (CLL) narrows that down to the column. For each column in a model, source or snapshot, it traces where the data came from and where it goes next. In Catalog it needs an Enterprise or Enterprise+ plan and no setup. Open it from the column card on the Columns tab of a resource's details page. It is updated after every production or staging run.

    A failing data test is a typical case. A not_null failure on a column in a mart model may come from a column several models upstream that has no test. CLL lets you follow that column back to the exact point where the problem started, so you don't have to read every model in between.

    The column evolution lens tells you whether each step transformed the column or reused it as a Passthrough or Rename. Only transformed steps can introduce a bug, so this narrows down where to look. The Transformation column previews the formula that produced the value. Reused columns also inherit their description from upstream, as far back as the lineage goes. A description on a mart column may therefore have been written on a staging model, and that is where you edit it.

    CLL is built by parsing SQL, which limits what it can see:

    - It reflects select statements only, not joins or filters. - SQL that is ambiguous or too complex, such as complex lateral joins, causes a parsing error. - Python models can't be parsed, so they show a Python error. - Hardcoded table names instead of ref can cause an unknown error.

    In these cases the lineage may be incomplete, and Catalog shows a warning. To see the error details, expand the column's lineage graph and select the node.

    Checkpoint 4 of 8· Check yourself

    Which statement about column-level lineage in Catalog is wrong?

    Sources2

    4.Data health signals as a first triage step

    Before you trace lineage, data health signals tell you which resources need attention. Models, sources and exposures each get one of four states: Healthy, Caution, Degraded or Unknown. The signal appears in search results, in the Health column of resource pages and public model tables, and in the node details panel of the lineage graph. For sources it also shows freshness status.

    For triage, the useful distinction is between Caution and Degraded. Caution means something is missing or warning: no tests, a missing description, no build in 30 days, or an upstream freshness warning. Degraded means something is broken: the build failed, a test failed, or an upstream freshness check errored or hasn't run in 30 days. A model with no tests at all is never Degraded, which is one reason teams find untested models late.

    Model health states and what triggers them
    StateTriggered by
    HealthyBuilt successfully in last run and in last 30 days, tests configured and all passed, upstream sources fresh, has a description
    CautionNot built in 30 days, no tests, tests return warnings, upstream freshness warning, or missing description
    DegradedModel failed to build, failing tests, or upstream freshness check returned an error or has not run in 30 days
    UnknownNo job runs have processed the resource

    Checkpoint 5 of 8· Match them up

    Match each model health state to a condition that produces it

    Tap a term, then the definition that fits it.

    Checkpoint 6 of 8· Exam question

    A data engineer opens the Columns tab for a model in dbt Catalog and finds a warning that the column-level lineage graph is incomplete for two of the model's source columns. Which two situations are documented causes of this kind of column-lineage parsing gap? (Select two.)(Select 2)

    Sources3

    5.Finding slow, failing and expensive models

    Model performance turns run history into a list of what to fix. It is available on Enterprise and Enterprise+. In Catalog, select your project and open the Performance tab. The overview ranks every model three ways: most executed (total count), longest average execution time, and most failures, split into run failures and test failures. You can filter by environment and job type. History goes back up to three months, and the default view is the last two weeks.

    Each ranking calls for a different fix. A model that is slow but runs once a day is a refactoring candidate. A model that is quick but runs in every hourly job may be a job configuration problem, because it is rebuilt more often than its data changes. A model with a high failure rate is a reliability problem before it is a cost problem.

    Each model's details page has its own Performance tab. Build time shows the average and its trend, Build count shows how often the model was built or reused, including failures, Test results shows pass and fail rates, and Consumption queries shows who queries it downstream. Click a data point on the Build time or Build count chart to see that day's job runs. Each row links to the run details, so a sudden jump in build time can be traced to the run that caused it.

    Checkpoint 7 of 8· Put it in order

    Put the steps for reaching a single model's cost and performance data in order

    1. 1.Navigate to the model, by search or via Models under Project assets
    2. 2.Click your project from the file tree
    3. 3.Open the Performance tab on the model's details page
    4. 4.From the main menu, go to Catalog

    Cost Insights adds warehouse cost to the same model page. You also find it on the project dashboard and the job details page. It works with Snowflake, BigQuery, Databricks and Amazon Redshift (preview). The Cost insights, Usage and Query run time tabs show each model's estimated spend over time. Show table breaks the figures down, the All and Jobs buttons switch between project totals and per-job figures, and Download exports a CSV.

    What the Usage tab measures on each warehouse
    WarehouseUsage unit
    SnowflakeCredits
    BigQuerySlot hours or bytes scanned, combined into one number
    DatabricksDatabricks Units (DBUs)
    Amazon Redshift ServerlessRPU-hours
    Amazon Redshift ProvisionedNode-hours

    These figures are estimates for optimisation, not for reconciling your bill. They can differ from the bill for several reasons:

    - Snowflake doesn't attribute cost to queries that run in about 100 milliseconds or less, so totals can be lower than the Snowflake billing dashboard. - Redshift shows $0 until you configure rpu_price_per_hour or node_price_per_hour. - Redshift prices each query as if it ran alone, so concurrent queries can add up to more than the bill.

    Cost reduction is calculated as average_cost_per_build * reuse_count, counting models that dbt State or state-aware orchestration reused instead of rebuilding. If those features were enabled before Cost Insights, it needs a full build within the last 10 days as a baseline. If no reduction figures appear, run a full build.

    Checkpoint 8 of 8· Exam question

    In dbt Catalog's multi-project view, an analyst clicks a public model that belongs to an upstream project and a details panel opens with General, Columns, and Relationships tabs. The analyst wants to find every downstream project currently consuming this specific public model. Which part of the panel should they open?

    Sources456

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.A successful CI run refreshes Catalog, so new models appear there as soon as the PR's CI job passes.Why is that wrong?

      Only production and staging runs, including deploy and merge jobs, update Catalog. CI runs are ignored.

      Covered in Where Catalog's picture of a project comes from

    2. 2.The default lineage graph shows every model defined in the project.Why is that wrong?

      By default it shows applied state: models that have been built and are available to query.

      Covered in Reading the lineage graph to trace cause and impact

    3. 3.Column-level lineage shows how a column is used in joins and filters, so it fully explains row-level discrepancies.Why is that wrong?

      CLL follows columns through select statements only. Joins and filters are not reflected.

      Covered in Column-level lineage for pinpointing breakages

    4. 4.Cost Insights totals should match the warehouse invoice, so a gap means misconfiguration.Why is that wrong?

      The figures are estimates for visibility and optimisation. Snowflake skips very short queries, and Redshift prices each query as if it ran alone.

      Covered in Finding slow, failing and expensive models

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “The model appears in the run_results of a dbt build, dbt run, or dbt clone command, regardless of the run's success or failure status.”
      ↩︎ Where Catalog's picture of a project comes from
      “If an environment has had no job runs in the past 3 months, all metadata for that environment is purged.”
      ↩︎ Where Catalog's picture of a project comes from
      “The graph of very large projects might not render so you can select a subset of nodes by using selectors, instead.”
      ↩︎ Reading the lineage graph to trace cause and impact
      “By default, Catalog excludes these resources from the full lineage graph unless a search query returns them as results.”
      ↩︎ Reading the lineage graph to trace cause and impact
      “Catalog uses the metadata provided by the Discovery API to display the details about the state of your dbt project.”
      ↩︎ Key concept
      “Note that CI jobs do not update Catalog.”
      ↩︎ Exam trap 1
      “it shows models that have been successfully built and are available to query, not just the models defined in the project.”
      ↩︎ Exam trap 2
      “Note that CI jobs don't update Catalog. This is because they don't reflect the production state and don't provide the necessary metadata updates.”
      ↩︎ Checkpoint
      “By default, Catalog shows the project's applied state lineage.”
      ↩︎ Prediction
      “All selectors are available for use, except those requiring a state comparison (result, source status, and state).”
      ↩︎ Checkpoint
    2. 2.
      “a failing data test on a particular column in your dbt model might've stemmed from an untested column upstream.”
      ↩︎ Column-level lineage for pinpointing breakages
      “You can access CLL from the column card in the Columns tab in the Catalog resource details page for a model, source, or snapshot.”
      ↩︎ Column-level lineage for pinpointing breakages
      “A reused column, labeled as Passthrough or Rename in the lineage, automatically inherits its description from the source and upstream model columns.”
      ↩︎ Column-level lineage for pinpointing breakages
      “Column-level lineage reflects the lineage from select statements in your models' SQL code.”
      ↩︎ Exam trap 3
      “It doesn't reflect other usage like joins and filters.”
      ↩︎ Checkpoint
    3. 3.
      “using the indicators Healthy, Caution, Degraded, or Unknown.”
      ↩︎ Data health signals as a first triage step
      “For sources, the data health signal also indicates the source freshness status.”
      ↩︎ Data health signals as a first triage step
      “Unable to determine health of resource; no job runs have processed the resource.”
      ↩︎ Checkpoint
    4. 4.
      “displays the longest-running models, those most frequently executed, and the ones with the highest failure rates during runs/tests.”
      ↩︎ Finding slow, failing and expensive models
      “Select the time horizon using the filter, which defaults to a two-week lookback.”
      ↩︎ Finding slow, failing and expensive models
      “Each row in the table provides a direct link to the run details if you want to investigate further.”
      ↩︎ Finding slow, failing and expensive models
    5. 5.
      “Costs will appear as $0 until you configure rpu_price_per_hour (serverless) or node_price_per_hour (provisioned) in Cost Insights settings.”
      ↩︎ Finding slow, failing and expensive models
      “Snowflake doesn't attribute cost to queries that run in roughly 100 milliseconds or less.”
      ↩︎ Finding slow, failing and expensive models
      “Cost estimates are intended for visibility and optimization, not billing reconciliation.”
      ↩︎ Exam trap 4
    6. 6.
      “at least one full model build must occur within the last 10 days to establish a baseline for cost reduction calculations.”
      ↩︎ Finding slow, failing and expensive models
      “Go to the the Performance tab on the model's details page.”
      ↩︎ Checkpoint

    Spotted a mistake, or was something unclear? Tell us.