Lineage and impact

Asset and column lineage, and how Nistor computes what a change or a failure affects downstream.

Lineage is the part of the graph that says how data moves: which table feeds which table, which column is computed from which columns, which report reads which cube. Nistor uses it to answer two questions. Where does this come from (upstream)? What depends on this (downstream)? The second question is impact analysis; the console calls it "Blast Radius".

Concepts explains how tools report what they observe and how the graph is built. This page goes deeper on the edges and on what Nistor computes from them.

Two levels#

Level The graph records You use it to
Asset For each node, its ancestors and descendants. Processing nodes, such as Dataform actions, sit between the tables they read and the tables they write. Trace a table back to its sources, or a report back to its cubes and tables.
Column For each column of a node, its source columns and, when the SQL shows one, the expression that derives it. Find which source columns a figure comes from, and which columns a change to one column reaches.

The compiler role builds the graph from what each tool discovers, and the backend serves the last graph it loaded. A change in a source system appears in lineage once the compiler has picked it up.

Where lineage comes from#

Tool Reports
Google Cloud Table lineage from view definitions and Dataform compilation results, column lineage parsed from SQL, and links between services (a Pub/Sub subscription to the service it calls, for example).
MicroStrategy The relations between its objects (cubes, reports, dashboards, documents) and the tables behind them, and column lineage for cubes and reports, parsed from their SQL.

Column lineage is parsed from SQL, so it is only as complete as the parser's reading of that SQL. A column with no traced source has has_lineage set to false.

Read lineage#

A node's page in the console has a Lineage tab. The same data is available from the API, under /api/v1. Reading it needs a signed-in user and no other permission.

Route Returns
GET /dependencies/ancestors/{id}, GET /dependencies/descendants/{id} Every upstream or downstream node, with the processing nodes that connect them. Query parameters: max_depth, exclude_patterns (regular expressions on node ids), include_scheduler_deps.
GET /dependencies/first_ancestors/{id}, GET /dependencies/first_descendants/{id} Direct neighbours only.
GET /lineage/columns?node_id= Every column of a node, with a one-line derivation summary and its source columns.
GET /lineage/column_field_group/{node_id}?column_name= The columns in other tables that hold the same field (see below).
GET /lineage/erd/{node_id} The table and its direct neighbours as an entity-relationship bundle: columns, table edges and column edges.

Over MCP, nistor_get_lineage returns upstream and downstream lineage to an assistant; see MCP server.

Same-field columns#

A field is often copied across tables (SELECT customer_id) or renamed (customer_id AS cust_id). Nistor walks the column edges that are pure copies and groups the columns that hold the same field. A copy has exactly one source column and no operator.

With SAME_FIELD_RELAXED_PASSTHROUGH_ENABLED (on by default), wrappers that keep the value also count as copies: TRIM, CAST, UPPER, LOWER, COALESCE and their relatives. SAME_FIELD_PASSTHROUGH_KINDS selects which: all by default, or a comma-separated subset of whitespace, cast, case_fold and coalesce. A group holds at most 50 columns unless you pass max_group_size, up to 500.

Impact analysis#

GET /api/v1/nodes/{node_id}/impact walks the graph downstream from a node, breadth first, and reports what it reaches.

Parameter Default Meaning
max_depth 3 (1 to 20) How many edges to follow.
exclude_patterns none Regular expressions on node ids. A matching node is left out, and the walk does not continue through it.
include_scheduler_deps false Also follow the links that rules create: a node reaches the nodes that the rules it triggers act on.
since none A timestamp. Adds write evidence from the lineage ledger (see Row-level evidence).

The response has:

Field Contents
affected_nodes Every downstream node, with its type, its distance from the origin (depth) and its console URL.
rules The scheduling rules that target an affected node: executor type, priority, status, and which affected nodes they target.
dq_checks The rules on affected nodes that run the data_quality_check executor. That executor comes with the Data quality module, so without it the list is empty.
scheduled_actions Actions already queued against an affected node.
summary The four counts.

Impact analysis follows edges in the graph and nothing else. A consumer that Nistor has no edge to, such as a notebook or a service that reads a table directly, is not in the answer.

Over MCP, nistor_impact_analysis calls this route.

Impact tier#

Nistor classifies a blast radius by the number of downstream nodes: critical from 20, high from 10, medium from 3, and low below that. The count says how wide a failure reaches, not how important the nodes are.

GET /api/v1/dashboard/impact-summary returns the tier for every ongoing incident at once: the union of what each incident's affected nodes reach, the tier, and up to three downstream consumers, dashboards first. The console's incident views read it. The answer is cached for 60 seconds.

Impact of a rule#

GET /api/v1/rules/{rule_id}/impact starts from the nodes a rule resolves to and merges what they reach. It adds the users subscribed to the affected nodes and a 30-day cost estimate per node. The cost estimates need the FinOps module and are empty without it. Rule impact belongs to the scheduling capability (see Rules and scheduling); node impact is always available.

Row-level evidence#

Edges describe the structure of your pipelines. Two optional features add evidence of what actually happened. Both are off by default.

LINEAGE_LEDGER_ENABLED (default false) makes the backend record a ledger entry for each BigQuery write event it receives: inserts, merges, creates, updates, deletes, loads and streaming writes. An entry holds the destination table, the writer, the job, the source tables, the row counts and the shape of the write (an append, a merge, a full rewrite and so on). With the ledger on and since set, impact analysis adds to each affected node the first write after since, the number of writes, the rows written, and confirmed_from_origin, which is true when a write lists the origin node among its sources.

The ledger separates a measured zero from a missing measurement. A BigQuery table reports writes_since: 0 only when the window starts after the ledger's earliest entry. Any other node, or an older window, reports nothing, and you must not read that as "nothing was written".

The row-trace routes under /api/v1/lineage need the lineage:row_trace permission. Of the role templates only tenant-admin, which holds every permission, includes it, so an administrator grants it to anyone else.

Route Returns
row_trace The ledger's write history of a BigQuery table and, recursively, of the sources that fed each write.
row_journey The ledger write that most likely produced one row's current state, matched from the row's SYS_* audit values, and the writes upstream of it.
row_preview Up to 100 rows of a BigQuery table, read through the BigQuery API with the node's connection (no query job). Columns with a policy tag are left out.
provenance_coverage Per BigQuery project, how many tables carry SYS_* provenance columns (a load id, an ingestion reference, a row-key hash, an update timestamp).

row_trace can also look up one row by a key column that you name, and return that row's SYS_* audit columns. That lookup runs a BigQuery query, so it needs ROW_TRACE_BQ_PROBES_ENABLED (default false) and a backend identity that can read the table (roles/bigquery.dataViewer). It refuses a query whose dry-run estimate is above ROW_TRACE_MAX_SCAN_BYTES (30 GB by default).

What needs what#

Capability Needs
Asset and column lineage, node impact, same-field groups, the entity-relationship bundle Open source, always on.
Rule impact The scheduler capability.
Primary-key and personal-data flags on the bundle's columns The Catalog module. Without it, no column is flagged.
Table-to-dashboard links from Castor on the lineage view The Catalog module, which stores the links. Nistor draws them as a separate, badged overlay, because Castor's matching is heuristic. Set LINEAGE_CASTOR_LINKS_ENABLED to false to turn the overlay off.
Data-quality checks in an impact answer The Data quality module.
Cost estimates in a rule impact answer The FinOps module.
Write evidence and row trace LINEAGE_LEDGER_ENABLED, off by default. The row lookup also needs ROW_TRACE_BQ_PROBES_ENABLED, off by default.

The modules are part of Nistor Enterprise. The settings are environment variables of the backend; see Configuration.

Edit this page on GitLab

↑ ↓ to moveEnter to openEsc to close