See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
The backward question and the forward question
Lineage runs upstream. Someone points at a KPI on a dashboard and asks why it moved, and the answer is a path: dashboard, mart, staging model, raw event, source system, with the transformation at each hop. The reader is usually not an engineer, and the useful output is a story that ends at something they recognize.
Impact analysis runs downstream. An engineer is about to rename a column, drop a table, or change a grain, and the question is what depends on it. The answer is not a path, it is a set: every consumer reachable from this node, deduplicated, with an owner attached to each one. Nobody reads that set as a narrative; they read it as a list of people to warn and tests to run.
Because the shapes differ, the same graph fails at one job while succeeding at the other. A lineage view that expands one hop per click is fine for tracing a single path backward and useless for enumerating forty downstream consumers.
What impact analysis needs that lineage graphs often lack
Owners. A downstream set without names is a research project. The moment each consumer carries an owner and a team, the impact review turns into a message, which is the only output that changes anyone behavior before the deploy.
Consumers outside SQL. Warehouse-derived lineage stops at the last table. The things that break are frequently past that line: a dashboard calculation, a scheduled export, a reverse ETL sync into the CRM, a feature table read by a model, a spreadsheet somebody refreshes monthly. Those edges are declared by humans, not parsed, and a graph that omits them will report a clean blast radius for a change that takes down a sales report.
A stopping rule. Downstream traversal grows fast, and a set of 300 objects is the same as no answer. Useful impact analysis cuts at the boundary that matters: consumers that are externally visible, contractually promised, or owned by another team.
Running an impact review that fits in a pull request
The review is four steps: name the object being changed, list its direct consumers, expand only the consumers that cross a team or system boundary, and attach an owner to each survivor. Anything you can verify with a test goes into the test suite, and the rest goes into a message sent before the merge, not after the incident.
On a Datadef canvas that traversal is manual and deliberate. Each node carries a dataOwner, a dataSteward, and a teamInCharge list, so the downstream set converts into a notify list rather than into a research task. canvas_add_lineage takes up to a hundred links in one call, enough to record a real mart in a single pass, and validate_canvas reports a circular flow as an error with the offending path spelled out, so a downstream walk always terminates.
Impact review checklist
1. object changed: stg_orders.customer_email
2. direct consumers: fct_orders, dim_customers
3. crossing a boundary: revenue dashboard (Finance)
CRM sync (RevOps)
4. owner to notify: Finance lead, RevOps lead
5. covered by a test: fct_orders row count + not-null
Everything not covered by a test becomes a message sent
before the merge.The two commands that produce the list
In a dbt project the downstream set is a selector rather than a research task. dbt ls --select stg_orders+ --resource-type model prints every model downstream of the node, and the same command with --resource-type exposure prints the declared consumers outside the project, which is the half people forget. Both read the manifest, so they answer in a second and they answer about the code as it is rather than as somebody remembers it.
The test half is dbt build --select state:modified+ --defer --state ./prod-manifest, run in CI against the production manifest. It builds what changed and everything downstream of it, deferring unchanged upstream models to production instead of rebuilding the warehouse. What that covers is models. What it does not cover is any consumer the exposure list just printed, and that gap is exactly the message you send before merging.
If the project declares no exposures, the second command returns nothing and the review is quietly incomplete. Adding exposures for the dashboards and syncs that matter is smaller than it sounds: it is the same handful of consumers that turn up in every incident.
# everything downstream, inside the project dbt ls --select stg_orders+ --resource-type model # and outside it: only what someone declared as an exposure dbt ls --select stg_orders+ --resource-type exposure # build the change and its downstream, defer the rest to prod dbt build --select state:modified+ --defer --state ./prod-manifest
FAQ
Is impact analysis just lineage read backwards?
Do I need column-level lineage to do impact analysis?
Why do impact reviews miss dashboards and exports?
How far downstream should an impact review go?
Can a diagram support impact analysis, or do I need a platform?