Data Lineage Guide

Data lineage vs impact analysis: same graph, opposite direction

By the engineer who builds Datadef, from client work on data platforms · Reviewed August 21, 2026

The two terms get sold together and used interchangeably, which is why teams buy a lineage tool and then discover it does not answer the question they actually had. Lineage is the backward question: where did this number come from and how was it calculated. Impact analysis is the forward question: if I change this column tomorrow, what stops working and who do I tell. Same edges, traversed in opposite directions, producing answers with different shapes.

6 min readFor data teams reviewing a schema change before it ships

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

131/20003 credits left
Try:

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?

It is the same graph traversed downstream instead of upstream, but the useful output differs. Lineage produces a path a person reads as a story. Impact analysis produces a deduplicated set of consumers with owners attached, which is read as a list of people to warn and tests to run.

Do I need column-level lineage to do impact analysis?

For a column rename or a type change, yes, otherwise every table that touches the model appears in the blast radius and the review is several times larger than the real risk. For dropping a table, changing a schedule, or moving a dataset between systems, table-level lineage answers it completely, because the whole object is the thing that moves.

Why do impact reviews miss dashboards and exports?

Because warehouse lineage is derived from SQL, and dashboard calculations, scheduled exports, reverse ETL syncs, and spreadsheets are not SQL the warehouse ever sees. Those consumers have to be declared by a person, which is why the last hop of most lineage graphs is the least complete part.

How far downstream should an impact review go?

Until the traversal leaves your team. Consumers inside your own project are covered by your tests. The ones that matter are the objects owned by someone else or visible outside the company, and those are the ones that need a message before the change ships.

Can a diagram support impact analysis, or do I need a platform?

A curated diagram works when the critical consumers are named on it and each one carries an owner. It stops working when nobody can enumerate the consumers any more, which is the point where automated discovery starts earning its cost.