cswork / libraryOpen practice workspace

Articles

Data Lineage Interview Questions: Impact Analysis, Column Lineage, and Missing Metadata

Prepare for data lineage interviews with worked impact analysis, column dependencies, missing metadata recovery, and practical coverage checks for engineers.

A finance dashboard changes after a harmless-looking source update. The pipeline is green, the table still exists, and nobody can explain which customers were affected. This is where data lineage becomes an engineering problem: you need evidence connecting a particular input, transformation, execution, and downstream decision.

For data lineage interview questions, answer by identifying the dependency at the right level, tracing downstream consumers, and separating observed relationships from missing metadata. A column graph helps narrow impact, but an absent edge does not prove independence. Strong answers explain how to recover evidence before approving a change.

The cases below are original practice scenarios for data engineers and analytics engineers, not reported employer questions. OpenLineage documentation supplies the terminology; the investigation plans and numerical examples are editorial recommendations.

What should a lineage answer establish first?

Start with the decision. Is someone renaming a field, correcting historical records, deleting a source, or investigating an incorrect metric? Each question requires different evidence. A rename may break compilation; a status correction can silently change results without any schema change. Asking this distinction prevents a broad catalog tour from replacing an actual answer.

Next establish identity and time. In this guide, an asset is a dataset in a named environment, and an execution is one attempt to run a transformation. Production orders and development orders must not become the same node simply because both tables are called orders. Yesterday's successful execution also should not overwrite the evidence of today's failed attempt.

OpenLineage's object model separates datasets, jobs, and runs. In an interview, connect those concepts to a practical statement: this production job, at this code revision, read these inputs and attempted to write that output. Then explain which portions are measured and which are inferred from source code.

How do table and column lineage answer different questions?

Table lineage says that daily_revenue depends on orders. Column lineage explains which inputs contribute to daily_revenue.amount. That distinction changes the investigation when a source contains hundreds of fields and only one is changing. However, column mapping must include influences beyond copied values.

Consider this intentionally small transformation:

SELECT order_date, SUM(net_amount) AS paid_revenue
FROM orders
WHERE status = 'paid'
GROUP BY order_date;

net_amount contributes values to the sum. status controls which records enter it, and order_date controls grouping. OpenLineage's column facet distinguishes direct derivation from indirect influence, including filters and grouping. A tool that records only selected value expressions can therefore understate impact.

Explain the consequence rather than reciting names: changing status can change revenue even though the output contains no status column. If the interviewer asks whether every supported connector captures that dependency, the answer is to inspect the integration and emitted metadata. The specification's vocabulary is not a promise of universal capture.

Can you trace an impact calculation by hand?

Assume three orders on one day, with amounts already expressed in the same currency. There are no refunds, duplicate order identifiers, or joins in this fixture. Those assumptions make the expected result unambiguous.

OrderNet amountOriginal statusCorrected status
A120paidcancelled
B80paidpaid
C50pendingpending

Originally, paid revenue is 120 plus 80, or 200. After correcting A, it is 80. The difference is negative 120. A copied customer_name field would not explain this change; the relevant edge is the status filter's influence on row membership.

Now add two consumers: a dashboard reads daily revenue, and a monthly export sums daily revenue. Both are candidates for impact. An unrelated address report that reads only customer addresses is not implicated by the available graph. Say "not implicated by the available graph" until coverage is verified; otherwise the wording quietly converts incomplete evidence into certainty.

The worked answer should finish with an action: recalculate the affected day, compare downstream totals, notify the export owner, and determine whether an already delivered file needs replacement.

How would you find the downstream blast radius?

Begin at the changed field and follow relevant downstream edges. Record each consumer, owner, refresh schedule, and materialization boundary. A view may expose the change on its next read, while a table or exported file can retain older results until rebuilt. "Everything downstream" is an inventory, not yet a recovery plan.

Suppose the correction arrives at 11:00. The dashboard refreshes hourly, the monthly table builds nightly, and an external file was delivered at 09:00. The dashboard may correct itself sooner than the historical export, even though both depend on the same calculation. Prioritize the consumer whose stale result can trigger an irreversible business action.

For a rename, inspect runtime queries and dashboards as well as transformation code. A notebook assembled by an analyst may not belong to the scheduled pipeline graph. Ask whether the inventory includes ad hoc access, cached extracts, and external consumers. Document uncovered categories rather than pretending that graph traversal can discover assets nobody has registered.

What does a missing lineage edge actually mean?

A missing edge has several possible explanations: the dependency does not exist, an instrumented job has not run, an event was dropped, parsing failed, or asset identities were normalized differently. These explanations lead to different actions. Deleting the source immediately is only defensible after the ambiguity is resolved sufficiently for the risk involved.

Use a compact evidence ladder during the interview:

ObservationWhat it establishesWhat remains unresolved
SQL references the sourceA declared dependencyWhether this version executed
Query history shows a readAn observed accessWhether every output was captured
Run event names input and outputA reported execution relationshipInstrumentation completeness
No catalog edgeNo displayed relationshipWhether the source is unused

This distinction is especially useful under pressure. You can say, "I have one observed read and a missing catalog edge, so I will investigate ingestion before approving removal." That answer is both actionable and appropriately bounded.

How do you reconstruct lineage after an instrumentation failure?

First establish the failure interval. Compare the last known good lineage event with job histories, deployment times, and collector health. If jobs kept running while events stopped arriving, the issue may be collection rather than data execution. Preserve event payloads and identifiers before retrying ingestion so duplicates can be recognized.

Next recover a minimal chain from authoritative artifacts: scheduled job identity, executed query text where available, code revision, referenced datasets, output identity, and execution time. If a dynamic query was assembled at runtime, the checked-in template may not identify the final table. Query history can be stronger evidence for that particular execution.

Represent recovered relationships with provenance and confidence. A human-confirmed mapping from an executed query should be distinguishable from a parser's guess about a template. Avoid inventing run identifiers or marking an execution successful simply because its output table exists.

Finally, repair the producer or collector and compare a new controlled execution with the reconstructed chain. Backfilled metadata should supplement the historical record, not erase the period when coverage was unknown. Keep a list of consumers still awaiting verification.

Why do retries and versions complicate the graph?

A scheduled job can have a failed attempt followed by a successful retry. The logical job is the same, but the attempts are separate executions. OpenLineage's run cycle describes lifecycle events such as start and completion or failure; consumers need to interpret those events without collapsing contradictory outcomes into one timeless edge.

Imagine attempt one reads partition P but fails before committing its output. Attempt two reads a corrected P and succeeds. A graph that merges inputs from both attempts could imply that the final result used the first version. During an incident, retain the association between each attempt, its inputs, and its outcome.

Versioning also matters for code. At 08:00 the job sums gross revenue; at 12:00 a deployment changes it to net revenue. The dataset names remain unchanged, but their relationship has different meaning. An impact answer should identify the active transformation version for the period being investigated, not merely draw the latest graph.

How do dynamic SQL and opaque functions change your answer?

Dynamic SQL can select a table name from a configuration value, while a user-defined function can hide field usage inside code the SQL parser cannot inspect. State the resulting evidence gap explicitly. A parsed query may reveal the surrounding table dependency without proving the function's internal column mapping.

For example, score_customer(customer_payload) returns a score, but the payload contains income, postcode, and tenure. Unless you inspect the function and its version, you cannot confidently claim that only tenure influenced the result. Record the payload as an input and mark finer granularity unresolved.

Propose a concrete improvement: capture resolved query text, instrument the function boundary, maintain a reviewed mapping, or add a contract test for a known transformation. Choose according to the source of uncertainty. Maintaining a manual mapping can be reasonable for one stable function; it becomes fragile when dozens of unreviewed versions change weekly.

How can you measure coverage without misleading people?

Choose a denominator before presenting a percentage. "Ninety percent lineage coverage" might mean datasets with any edge, scheduled jobs emitting events, or critical output columns with verified dependencies. Those are different measurements and should not share an unlabeled dashboard number.

Suppose a platform has 100 scheduled production jobs, 80 emit events, and only 60 include usable output identities. Event emission coverage is 80 percent; usable output coverage is 60 percent. Neither proves that 60 percent of all business dependencies are known. Ad hoc queries and external extracts remain outside the denominator.

Track freshness separately. A perfect-looking dependency last observed six months ago may be less useful than a partial mapping confirmed this morning. For a critical report, propose checks on recent successful executions, expected producer versions, and unresolved edges. Select targets from business risk rather than inventing a universal acceptable coverage threshold.

How would you approve a breaking source change?

Use the graph to identify candidates, then validate the change against their actual contracts. A numeric type widening may preserve a calculation but break an export parser. Dropping a field may leave warehouse jobs healthy while breaking a customer-facing extract. The approval should name the affected behavior, not merely count nodes.

For the revenue fixture, a useful migration would retain the old field temporarily, update and test consumers, compare totals over representative dates, and define a retirement condition. Include empty days, cancelled orders, and corrected historical records in the comparison. If the old and new definitions intentionally differ, document the expected differences instead of demanding false equality.

Specify rollback carefully. Reverting transformation code does not restore an already replaced export or undo a consumer's decision. Record who can stop delivery, who can regenerate artifacts, and which historical partitions need repair. This turns lineage into operational coordination rather than an attractive diagram.

How should you practice a complete interview response?

Give yourself a source change, a graph with one missing edge, and three consumers with different refresh schedules. Spend the first minute clarifying the change and the observation window. Then trace one result numerically before discussing platform architecture. This makes hidden assumptions visible early.

A strong closing answer could be: "The status correction changes paid revenue from 200 to 80. I will verify the filter dependency, refresh the affected daily result, inspect the monthly aggregate, and contact the delivered-file owner. The notebook consumer remains uncertain because its queries are outside current capture. I would hold deletion until that gap is investigated."

Practice a second round where the interviewer removes query history or changes a function version. Your response should become narrower as evidence disappears. The goal is a defensible decision with named unknowns, not a claim that lineage software can reconstruct every dependency automatically.

Sources and Further Reading

Official documentation checked September 24, 2026. Examples and recovery policies above are original exercises; connector behavior must be verified in the deployed version.