Skip to main content

Run Results and Performance

A dbt build with a hundred nodes used to be one long scrolling log. Now every run, in the editor and on every job run, also gets a Run results view: one row per node with its status, time, log, and SQL, live while the run is going. A Performance view tells you which nodes made the run slow and what to change. A quiet run explains that it is still working, and a run that stops says why.

dbt build --select +fct_revenue_dailyRunningA build starts and every node appears as a row the moment dbt picks it up
OutputRun resultsPerformanceProblems
Pass 0Warn 0Error 0Skip 0Running 3
Nodeslive
stg_ordersviewRunning
dim_customertableRunning
not_null_dim_customer_idtestWaiting
fct_orderstableWaiting
fct_revenue_dailytableWaiting
RerunRerun failed + skipped (5)
stg_ordersLogSQL
12:04:31 1 of 96 START sql view model dwh.stg_orders ... [RUN]
[dbdeux] still running: 41 of 96 done, 1 statement(s) executing on the warehouse: dim_customer (8m 12s). dbt prints nothing until a statement finishes; this run is not stuck.
Open in editorShow in DAGAsk Atlas to fix

Every Node, Live​

Open the Run results tab in the editor's bottom panel, next to Output. On the left, Commands lists the dbt commands you ran, newest first, with how many nodes failed. Pick one to see its nodes on the right.

  • Counters across the top: Pass, Warn, Error, Skip, and Running, updated while the run is going. Click a counter to show only those nodes, or type in Filter nodes to find one by name.

  • One row per node: models, tests, seeds, and snapshots, each with its status and how long it took. Until the first node starts, the tab says dbdeux is getting the project ready.

  • Open a node to read its own Log and the SQL dbt ran for it. You don't have to scroll the whole build to find one model's lines.

  • Why it failed: a failed node puts the warehouse's error message at the top, and a warning shows its message the same way.

  • Next steps on every node: Open in editor opens the model's file, Show in DAG finds it in the lineage graph, and Ask Atlas to fix hands the error to Atlas.

  • While a run is going, the node that is running opens by itself and its log refreshes live, so you watch the work instead of a frozen screen.

  • The full command, every flag included: the run header shows exactly what the run started with, such as dbt --debug build --select +fct_orders --threads 8.

  • The reason sits under the name: a failed node shows the warehouse's message right in its row, and nodes stopped by a cancel are marked Cancelled.

  • Every node keeps its own log, so the log of a node from a 900-node build is one click away after the run.

Rerun What Matters​

When a run finishes, Rerun runs the same command again. Rerun failed + skipped (N) runs only the nodes that failed and the nodes they took down with them. The tab stays open on the new run, so you can watch those few rows turn green.

The Same View on Every Job Run​

A job run's detail page has a Results tab with the same rows, counters, filters, and per-node log and SQL. When a scheduled run fails overnight, filter to Error and the node that broke is the only row left.

The Output Log Is Still There​

Output shows dbt's full text log exactly as before, with colors and timestamps. Run results is an extra view, not a replacement, so your habits and any copy and paste from the log keep working.

A Quiet Run Is Not a Stuck Run​

dbt prints nothing while the warehouse is working on a statement. A model that takes ten minutes used to look exactly like a run that had died. Now the run tells you what it is doing:

What you see in the OutputWhat it meansWhat to do
still running: 41 of 96 done, 1 statement(s) executing on the warehouse: dim_customer (8m 12s)The warehouse is still working on the statements named, with how long each has runNothing; it is a progress update. If it is the same model every time, check Performance below
A place in the queue, with how many runs are aheadThe run is queued behind other runs and starts as soon as there is roomNothing; the count goes down as runs ahead of yours start
Live log stream dropped; following the saved run log insteadYour browser lost the live connection. The run itself was not affectedNothing; the log keeps updating from the saved copy
statement limit reached: dim_customer has been executing for 61m 04sThe environment's statement time limit stopped the runFollow the advice in the line, see Statement Time Limit
run stopped before dbt finished: ...The run was stopped by the platform, for example during an update, or ran out of memory. The line names the statements that were executingRun it again. Models that finished are kept in the warehouse
A line saying the run was cancelledSomeone pressed CancelRun it again when you are ready

Every run reaches a clear end: if it is interrupted, it is marked with the reason in the Output, and Cancel always works.

Performance: Why a Run Was Slow​

Run results · Performance140 nodes · 38mAfter a run, the Performance tab lists the slowest nodes with what each one is built as
Slowest nodesTime
fct_web_leads_funnelview7m 34s
dim_customertable5m 27s
unique_fct_web_leads_funnel_rfqtest4m 20s
stg_nav_product_mappingtable2m 58s
fct_budget_general_ledgertable36.7s
What to change
Pick a slow node to see why it was slow and what to change. Fast runs show no advice at all.

The Performance tab, in the editor and on every job run's detail page, starts from the question you actually have after a slow run: which nodes took the time, and what should I change?

  • Slowest nodes: each with its type, how it is built (view, table, incremental, test), its time, and its status.
  • What to change: plain advice for the patterns that cost the most.
    • A view read by many models is computed again by every model that reads it. The advice names the view and tells you to build it as a table, so it is computed once per build.
    • A slow model gets pointed at what to check: a heavy view upstream, a missing filter on an incremental model, or a warehouse size too small for the work.
    • A slow test can be limited with a where config, run on a sample, or scheduled less often.
  • In Atlas Catalog too: the same advice appears under Recommendations on the model's detail page, next to its Performance history, so it is still there after the run scrolls out of view.

The Run Timeline​

Model timingPerformance tab
Thread lanes
Wall time18 min 40 s
Threads8 threads, 41% idle
Every model on its thread, start to finish, so idle time and long chains are visible at a glance

The Performance tab also draws the run as a timeline, for scheduled runs and editor runs:

  • Thread lanes: each model as a bar on the thread that built it, with how much of the threads' time was spent waiting on dependencies.
  • Critical path: the chain of models that decided the run's length is highlighted, with Critical path only to show just that chain.
  • What would finish the run sooner: a replay of the run at other thread counts, with the time each would save or no gain.
  • Previous run behind: the last run drawn faintly under this one, with the models that got slower (by 30% and 10 seconds or more) and whether the critical path changed.
  • Models reused by State or skipped are left out of the lanes and counted.

Resources: Was the Run Short of Memory or CPU?​

dbt --debug build --select +fct_orders --threads 8Every run reports how much memory and CPU it used, against what it had available
Resources
Memory peakPlenty of room
CPUPlenty of room
VerdictHealthy
Plenty of room: memory and CPU stayed well under the limit.
Threads
Automatic14816
Automatic picks a sensible number for what you run and your warehouse. The run log states the number it used.

Every scheduled run and every editor run reports what it used, in a Resources row on the job run's detail and in the editor's Results header:

  • Memory and CPU use, each shown against what the run had available.
  • A verdict first: plenty of room, or close to a limit with what to change, such as fewer threads for that job.

Threads, Chosen for You or Set by You​

The editor's run bar and the job wizard have a Threads option. Automatic picks a sensible number for what you are running and your warehouse, and the run log states the number it used. Choose your own number for one run, set it on a job (the job detail shows it), or keep --threads in the command; the command wins.

Runs That Finish on Their Own​

If a scheduled run is interrupted, dbdeux closes that attempt and starts the next one automatically, so a nightly build still finishes. The notification says how long the run was stuck and what happened next.

Why Each Model Ran​

The Why each model ran panel on a run's detail gives every model a verdict, rebuilt, reused or cloned, and the reason in plain words, such as "its SQL changed" or "an upstream model was rebuilt". Filter by reason or search for a model to see exactly why a run did the work it did.

Self-Healing Runs: Atlas Proposes the Fix​

Self-healing runsFailure summary
nightly_build · Failed
fct_ordersFailed: column amount_usd not found
Retries2 of 2 used
Proposed fix by AtlasAtlas is working on it
A scheduled run fails and its retries are used up

In Organization settings, turn on Propose fixes with Atlas after failed runs, and a scheduled run that fails after its retries gets a Proposed fix by Atlas card on its Failure summary within a few minutes:

  • The smallest change, explained: each changed file comes with the reason, and the card links the pull request. Anything Atlas should not change by itself is listed under Needs a human.
  • Clear states: Waiting for retries to finish, Atlas is working on it, Pull request opened, Could not propose, or Not attempted.
  • The run finishes itself: when the pull request is merged, the failed and skipped models run once more from the merged branch, and the card reads Fix merged, run resumed.
  • Unattended, if you want it (Business and up, off by default): Merge allow-listed fixes without a human merges a fix on its own when every change is of a kind you allowed and Slimmer CI passed. Every unattended merge is recorded on the run. The kinds are a SQL error in a model, a compile or Jinja error, a reference to a renamed or moved upstream object, a data conversion error, and a failing test adjusted in YAML.

Statement Time Limit​

On an environment's Overview tab, Statement time limit stops a run when a single dbt statement runs longer than the time you set, instead of holding the run, and the warehouse, for hours.

  • Choose No limit (the default), or a number of minutes. 60 minutes is a good starting point.
  • On PostgreSQL and the MotherDuck Postgres endpoint, the warehouse enforces the limit on each statement. On other warehouses, dbdeux stops the run when a statement passes the limit.
  • The Output names the node, how long it ran, and what to change. Usually the fix is to build a heavy view as a table, and the Performance tab shows you which one.

Which MotherDuck Compute Ran This​

For MotherDuck connections, the Output names the Duckling size the run executes on, for example MotherDuck Duckling: Standard. If a run is slow, you can see right away whether it ran on a small size, and change it from the connection. See MotherDuck.

How It Compares​

dbdeuxdbt Clouddbt Core on your laptop
Per-node results with status and timeYes, live while the run is going, in the editor and on job runsYes, on job runsRead the log or run_results.json yourself
Each node's own log and SQLYes, one clickYesSearch the log
Rerun only what failed or was skippedRerun failed + skipped, from the editor or a job runRerun from failure on jobsBuild the --select list yourself
Says a quiet run is still workingYes, names the statements on the warehouse and their timeNoNo
Says why a run stoppedYes, in plain words: cancel, time limit, platform stop, or memoryPartlyA bare error code
Advice on what made a run slowYes, names the view to build as a table, the slow model, or the slow testModel timing chart, no adviceNo
Stop runaway statementsPer environment Statement time limitJob-level timeoutWarehouse settings only