RETRIES & RESILIENCE

A federated build touches more machinery than a single-warehouse run: several engines, a data-movement lane, cloud warehouses that suspend themselves between uses. Failures in that world come in two kinds, and DVT refuses to treat them as one. A failure caused by your code or your data reproduces— retrying it doubles the time to a red and changes nothing — so it surfaces immediately, in the engine's own words. A failure caused by the machinery is transient — a crashed loader process, a warehouse answering mid-wake — and for exactly those, and only those, DVT retries on its own.

THE RULE — A NAMED LIST, NOT A JUDGMENT CALL

What retries is a closed, named list. There is deliberately no "retry anything that fails" mode, because a general retry is a masking machine: an engine refusing a malformed load, a missing grant, a table that isn't there — those reproduce on every attempt, and retrying them either doubles the latency of the red or, worse, papers over a real product bug with an eventual coincidental green. Every class on the list below earned its place by being observed, diagnosed, and verified transient. Everything off the list surfaces on the first try.

IN PLAIN DBT

dbt doesn't move data, so it never has to make this call — a connection blip surfaces as an adapter exception and rerunning is your job (or your orchestrator's). DVT owns a data-movement lane, so it owns that lane's weather too: the transient classes are handled inside the run, and what reaches you is either a green or a red worth reading.

CRASH CLASSES — THE LOAD LANE RETRIES ONCE

A process crash is not a verdict about your data. When the movement engine itself dies mid-load — a segmentation fault, a Go runtime panic, or Oracle's SQL*Loader racing itself over its streaming pipes under parallel loads — the load retries once. The same model on the same hop routinely lands clean seconds after a crash, which is exactly what makes these transient. A real load error — an engine refusal, a malformed option — still surfaces on the first try, because it would reproduce and a retry would only delay the answer.

The crash is never hidden: the log names the reason and the retry before taking it, and if the retry fails too, the red you get is the real one.

THE WAREHOUSE WAKE CLOCK — CLOUD ENGINES THAT SLEEP

Snowflake, Databricks and BigQuery warehouses suspend themselves when idle, and a suspended warehouse answers the first requests of its wake window with transient request errors — for minutes, not seconds. A quick retry lands inside the same window and fails the same way. So operations against these engines retry on a warehouse clock: 60 seconds, then 120. Extractions from them get the same treatment — a first quick retry at 20 seconds for ordinary blips, then a second that waits the wake clock. A partial download is deleted before any retry, so a resumed extraction can never append to a half-written file.

stg_orders: cloud extraction failed (request error) — retry 1/2 in 20s
stg_orders: cloud extraction failed (request error) — retry 2/2 in 120s

Membership in the cloud-transient set is decided by the observed failure class, not by whether something is marketed as cloud: local engines never take this branch, because their request errors reproduce and must surface first-try. And when both retries fail, the error says so honestly — labeled as a failure after the retries — so a genuine outage is never softened into a mystery.

For long-running builds there is also a cheaper answer than retrying through wakes: raise the warehouse's auto-stop timeout while the work runs, and put it back after.

WHAT NEVER RETRIES

Everything else. SQL errors, missing relations, permission refusals, type mismatches, constraint violations — the whole family of failures where the engine is telling you something true about your project. These surface immediately and verbatim, because the engine's own message is the most useful artifact a red run produces, and because an automatic retry of a reproducible failure is time spent manufacturing the same error twice.

DVT RETRY — THE OTHER LAYER

Everything above happens inside a run, automatically, at the level of a single extraction or load. One layer up sits dvt retry, which you invoke yourself: it re-runs exactly the nodesthat failed last time, skipping everything that already succeeded. Transient handling keeps the machinery's weather out of your results; dvt retry keeps a fixed model from costing you a full rebuild. They compose — a run that went red on a real bug is fixed, retried at the node level, and any transient blip inside that retry is absorbed the same way as always.