COLUMN LEVEL LINEAGE
Column Level Data Lineage: Column Level Lineage Tools and Column Lineage for dbt and Snowflake
Column level lineage maps a specific source field to the specific downstream field it produces, through every join and transformation in between. Traced automatically from warehouse query history and dbt metadata, wired into alerts, from 99 dollars a month.
14-day trial, no credit card, read-only connection
Alerted #data-eng 0.8s ago.
Downstream impact · consumers at risk
What is column level data lineage?
Column level data lineage is a map of how individual fields flow through your data stack: which source column produces which downstream column, through the joins, case statements, and aggregations in between. Table level lineage only records that one dataset feeds another, which during an incident tells you that eleven dashboards sit downstream without telling you which of them read the field that actually broke. Column level lineage answers that directly. Most platforms now offer some form of it, but every implementation has a documented gate and a documented failure mode: dbt column level lineage requires an Enterprise plan and reflects only select statements, Snowflake requires Enterprise Edition, Databricks Unity Catalog does not capture it for renamed objects or UDFs, and BigQuery drops to table level once a job creates more than 1,500 column links. Dataobservability parses column level lineage from warehouse query history and dbt metadata on every tier, starting at 99 dollars a month.
Last updated August 2026
Side by side
Column level data lineage compared
Swipe to see all columns →
| Where lineage comes from | Column level? | Plan or edition gate | Documented limits (from vendor docs, August 2026) |
|---|---|---|---|
| Dataobservability | Yes, warehouse and dbt, on every tier | All tiers, from $99 per month | Covers the connected warehouses (Snowflake, BigQuery, Databricks, Redshift) and dbt; systems outside them are not traced |
| dbt Catalog (renamed from dbt Explorer) | Yes, for models, sources, and snapshots | Enterprise and Enterprise+ only | Reflects lineage from select statements only, not joins or filters; parsing fails on Python models, JSON unpacking, lateral joins, and hardcoded table names used instead of ref |
| Snowflake ACCESS_HISTORY | Yes, via directSources and baseSources in objects_modified | Enterprise Edition or higher | Covers write operations; it is a view to query, not a graph to browse, and it stops at the account boundary |
| Databricks Unity Catalog | Yes, captured automatically for queries run on Databricks | Included with Unity Catalog | Nothing captured before September 1, 2024; lineage is not preserved through renames; RDDs, global temp views, checkpointed datasets and UDFs are not captured; both sides must be referenced by table name, not path |
| BigQuery (Knowledge Catalog, renamed from Dataplex Universal Catalog April 10, 2026) | Yes, for top level columns | Knowledge Catalog | Not collected for load jobs or routines; no upstream column lineage for external tables; falls back to table level above 1,500 column links per job; nested STRUCT and JSON fields unsupported |
| Amazon Redshift | No native column level lineage graph | n/a | SYS_QUERY_HISTORY and SYS_QUERY_DETAIL give you the SQL that ran; turning that into column edges is parsing work you own |
| Enterprise catalogs (Collibra, Alation, Informatica, IBM Manta) | Yes, with the deepest reach into legacy ETL | Quote only, no published price | Strongest on stored procedures and legacy ETL via static code analysis; heaviest to deploy and the slowest to buy |
| Open source (DataHub, OpenMetadata, OpenLineage) | Column level where the ingestion source supports it | Free, Apache 2.0 | Coverage varies by connector; you operate the metadata service, search index, database, and ingestion jobs yourself |
Positioning and pricing models are summarized in good faith from each vendor's public pages, August 2026. Verify current terms with the vendor.
What you get
What column level lineage gives you that a table level graph cannot
Impact analysis that names the two dashboards, not the eleven
When a source field starts arriving null, table level lineage returns every asset downstream of that table. Most of them never touch the field that broke. Column level lineage narrows the same question to the handful of models and dashboards that actually read it, which is the difference between paging four teams and paging one. It is the same query, answered precisely enough to act on.
A real answer to whether you can drop a column
Table level lineage can only ever tell you the table has consumers, so the safe answer to every schema change is no. That is how warehouses accumulate columns nobody has read in two years. Column level lineage tells you whether one specific field has any reader at all, which turns deprecation from a risky guess into a check that takes seconds.
Traced automatically, so it survives contact with production
Lineage drawn by hand is accurate the day it is drawn and wrong by the next quarter. Column edges parsed from warehouse query history and compiled dbt metadata reflect what actually ran last night, including the pipeline nobody documented and the CREATE TABLE AS somebody ran once in March that a dashboard now depends on.
Attached to the alert, not filed in a separate tool
Lineage earns its keep in the ten minutes after something breaks. When the column graph lives inside the monitoring system, a freshness or schema alert arrives with the affected downstream fields already resolved and the owner already named, instead of sending an engineer to open a second product and cross reference by hand.
No Enterprise plan gate on the feature that matters
The pattern across this category is that column level lineage is the thing held back for the top tier. dbt puts it on Enterprise and Enterprise+, Snowflake requires Enterprise Edition, and the enterprise catalogs will not quote a number at all. Column level lineage is included on every Dataobservability tier, starting at 99 dollars a month.
Column level lineage across systems, not inside one
Every warehouse native implementation stops at its own boundary. Snowflake traces columns inside Snowflake, Unity Catalog inside Databricks, dbt inside the dbt project. A stack that lands in Snowflake, transforms in dbt, and reports in BI has three partial graphs and no continuous one. Parsing both the warehouse history and dbt metadata joins those segments into a single path.
How it works
From connected to caught
Connect the warehouse read only
Point Dataobservability at Snowflake, BigQuery, Databricks, or Redshift with a read only role. It reads query history and information schema metadata, not the contents of your tables, so no customer data leaves the warehouse. Setup is a read-only connection and needs no agent, no pipeline changes, and no code in your dbt project.
Let it parse the column graph from what actually ran
The graph is built from the statements the warehouse executed plus compiled dbt metadata, which is why it includes the undocumented pipelines. Every select, join, and CTAS is parsed into column level edges, so you get the real shape of the stack rather than the shape somebody documented once.
Check the graph against a column you already understand
Before trusting it, pick a field you know cold, ideally one feeding an executive report, and walk it upstream to source. This is the step teams skip and then regret. It takes ten minutes, and it is the only way to learn where coverage is genuinely complete and where a stored procedure or a reverse ETL hop leaves a gap.
Wire the graph to alerting, then to change review
Route monitors so a freshness, volume, or schema breach resolves its downstream columns automatically and notifies the owner in Slack or PagerDuty. Once that is running, use the same graph in review: before a column is dropped or retyped, check whether anything reads it. Impact routing pays back the first time something breaks; deprecation safety pays back every quarter after.
What column level data lineage actually is, and how it differs from table level lineage
Column level data lineage records the relationship between individual fields rather than between datasets. Where a table level graph states that the raw orders table feeds the finance revenue model, a column level graph states that raw_orders.gross_amount, combined with raw_refunds.refund_amount through a left join and a coalesce, produces finance_revenue.net_revenue, which in turn produces the single number on the executive dashboard. The distinction sounds academic until the moment lineage is supposed to be useful. Consider a source system that starts sending nulls in one field. Table level lineage returns the full downstream set: four models, eleven dashboards, two reverse ETL syncs. That is a list of places to look, not an answer, because most of those assets never reference the broken field. Column level lineage returns the two dashboards that read it, one of which is the board report, and it returns them in seconds rather than after an afternoon of reading SQL. The same asymmetry governs schema change. Before dropping a column, a table level graph can only report that the table has consumers, which means the honest recommendation is always to leave it alone. That is precisely why warehouses accumulate hundreds of fields nobody has queried in years, each one carrying storage cost, cognitive cost, and a small risk of being used by mistake. Column level lineage answers the actual question, which is whether that specific field has a single reader anywhere downstream. It is also worth being precise about what column level lineage is not. It is not a data catalog, though catalogs often include it. It is not documentation, because documentation is written and lineage is derived. And it is not monitoring: the graph tells you what is connected to what, and it takes a monitoring system to tell you that something is wrong in the first place. Lineage without monitoring is a reference document that nobody opens; monitoring without lineage produces alerts with no blast radius attached.
Where column level lineage comes from on each platform, and exactly where each one breaks
Almost every vendor and every warehouse now claims column level lineage, and almost every implementation is partial in ways the marketing page does not mention but the documentation does. The specifics matter more than the claim, so here is what the vendor docs actually say as of August 2026. dbt renamed Explorer to Catalog, and column level lineage there is available on Enterprise and Enterprise+ plans only. Its documented behavior is narrower than most people assume: the lineage reflects select statements in your models, and explicitly does not reflect other usage such as joins and filters. It relies on SQL parsing, so it fails on Python models, on JSON unpacking and lateral joins where a column origin cannot be resolved, and on models that hardcode a table name instead of using ref. Snowflake exposes column lineage through the ACCESS_HISTORY view, where the objects_modified column carries directSources and baseSources, letting you trace a target column back through the chain to its original source columns. It requires Enterprise Edition or higher, it covers write operations, and it is a view you query rather than a graph you browse, which means someone has to build the traversal. Databricks Unity Catalog captures lineage automatically down to the column level for queries run on Databricks, and its limitations are unusually well documented: nothing captured before September 1, 2024, lineage is not preserved for renamed catalogs, schemas, tables, views, or columns, and RDDs, global temp views, checkpointed datasets, and user defined functions are not captured. Column lineage also requires both the source and the target to be referenced by table name rather than by path. BigQuery, through what has been called Knowledge Catalog since Dataplex Universal Catalog was renamed on April 10, 2026, supports column level lineage for top level columns, and drops silently to table level once a job would create more than 1,500 column level links. It is not collected for load jobs or routines, there is no upstream column lineage for external tables, and nested fields inside STRUCT or JSON types are not supported. Redshift has no native column level lineage graph at all; SYS_QUERY_HISTORY and SYS_QUERY_DETAIL give you the statements that ran, and converting those into column edges is parsing work you own. The pattern across all of them is the same. Column level lineage is real, it is gated behind a premium tier more often than not, and it stops at the boundary of the system that produces it.
The boundary problem, and why per platform lineage does not add up to a stack level graph
The most common disappointment with column level lineage is not that any single implementation is bad. It is that a normal analytics stack crosses three or four systems, and every native implementation traces only its own. Data lands in Snowflake, is transformed by dbt, is read by a BI tool, and is sometimes pushed back out through reverse ETL. Snowflake ACCESS_HISTORY can trace a column from the landing table to the mart, but it does not know that the mart column feeds a specific Looker field. dbt Catalog can trace a column through the transformation DAG, but only within the dbt project, so anything loaded by an ingestion tool or written by a stray notebook is invisible. Unity Catalog covers what runs on Databricks and nothing outside it. Each graph is accurate and each graph is a fragment, and the join between fragments is exactly where incidents propagate. This is the practical case for parsing lineage at the warehouse layer rather than relying only on any one tool. Warehouse query history sees every statement that touched the data, regardless of which orchestrator, notebook, or person issued it, which is why it catches the pipeline nobody documented. Adding compiled dbt metadata on top of that gives you the modeled intent alongside the executed reality, and the two together cover far more of a typical stack than either alone. The honest caveat is that this approach still has a boundary: it sees what reaches the warehouse. Transformations that happen entirely inside a BI tool, inside a stored procedure on a source system, or inside application code before load are not visible to query history, and no vendor claiming otherwise should be believed without a demonstration on your own systems. The useful question to ask any lineage vendor is not whether they support column level lineage. It is which of your specific sources produce column level edges, and what happens at the seams between them.
How to evaluate column level lineage without being fooled by a demo
Demos of lineage products are unusually misleading, because a lineage graph on sample data always looks complete. The sample project has clean SQL, no stored procedures, no Python models, no reverse ETL, and no column that gets built by string concatenation inside a case statement. Your warehouse has all of those. The single most useful evaluation technique is to bring a list of your genuinely awkward assets to the trial and check them first rather than last. Pick a column that is produced by a join across three tables, a column that comes out of a Python model or a UDF, a column that a BI tool computes rather than reads, and a table that was created once by hand and never documented. Trace each one. What you learn is not whether the product works, it is where the graph goes quiet, and every product has somewhere it goes quiet. A vendor who tells you plainly where coverage ends is more trustworthy than one who claims none of it matters. The second technique is to check refresh behavior, because a lineage graph is a claim about the present. Ask how often the graph rebuilds and from what. Nightly rebuilds from query logs mean that during an incident at 10am you are reading yesterday shape, which is usually fine and occasionally the exact reason you get the wrong answer. Manual entry, whether in a catalog UI or a diagram, is the mechanism that looks most complete in a demo and decays fastest in production. Third, check what the lineage is connected to. A graph you browse is worth far less than a graph that fires. If a schema change on a source column cannot automatically notify the owner of the dashboard that reads it, the lineage is documentation rather than infrastructure, and it will be consulted during the postmortem instead of during the incident. Finally, get the price in writing before the depth conversation ends, because column level lineage is the feature most often reserved for a tier that is quoted rather than published.
What column level lineage costs, and why the feature sits behind the top tier so often
Column level lineage is the clearest example of a pattern that runs through this whole category: the capability everyone needs is the capability held back for the plan nobody can price. dbt puts column level lineage on Enterprise and Enterprise+. Snowflake gates ACCESS_HISTORY behind Enterprise Edition. Among the commercial catalog and lineage vendors, the checks we have run repeatedly this year have turned up the same result each time: Atlan, Collibra, Alation, Informatica, IBM, Select Star, Secoda, and Coalesce all route buyers to a sales conversation rather than publishing a number, and Microsoft Purview is the partial exception only because it meters as an Azure service rather than because it publishes a product price. Datafold now redirects its pricing page straight to contact us. The practical effect on a data team is that you cannot scope the project before you start a procurement cycle, which is a real and underrated reason lineage initiatives die between the business case and the first demo. There is a defensible reason for some of this. Deep static code analysis of legacy ETL, the kind IBM Manta does across PowerCenter, SSIS, DataStage, and stored procedures, is genuinely expensive to build and genuinely variable in scope, and a published price would be close to meaningless. If that is what you need, accept the sales cycle and shorten it by bringing your source list and your hardest columns to the first call. But most teams asking for column level lineage do not need legacy ETL parsing. They need to know which downstream fields break when a source column changes, across a cloud warehouse and dbt, with the answer attached to an alert rather than sitting in a catalog. That is a bounded problem and it can be bought at a published price. Dataobservability includes column level lineage on all three tiers, at 99, 299, and 799 dollars a month, with a 14 day trial that needs no card. The trial exists mainly so a data team can verify the graph is accurate on its own columns before anybody writes a business case, which is the order those two things should happen in.
Questions buyers ask
Column level data lineage FAQ
What is column level data lineage?
Column level data lineage is a map of how individual fields flow through a data stack, recording that a specific source column produces a specific downstream column through the joins, case statements, and aggregations in between. It is more precise than table level lineage, which only records that one dataset feeds another. Teams use it for incident impact analysis, safe schema changes, and tracing a reported number back to its source.
What is the difference between column level and table level lineage?
Table level lineage records that one dataset feeds another. Column level lineage records which specific field produces which specific downstream field. The difference shows during an incident: table level lineage says eleven dashboards sit downstream of the broken table, while column level lineage says which two actually read the field that broke. It also decides change safety, because only column level lineage can tell you whether a column you want to drop has any reader.
Does dbt have column level lineage?
Yes, in dbt Catalog, which was renamed from dbt Explorer. It is available on Enterprise and Enterprise+ plans only, and covers models, sources, and snapshots. Two documented limits matter: it reflects lineage from select statements and not from joins or filters, and because it relies on SQL parsing it fails on Python models, JSON unpacking, lateral joins, and models that hardcode a table name instead of using ref.
Does Snowflake support column level lineage?
Yes. The ACCESS_HISTORY view in Account Usage carries column lineage inside its objects_modified column, using directSources and baseSources to trace a target column back through the chain to its original sources. It requires Snowflake Enterprise Edition or higher and covers write operations such as INSERT, MERGE, and CTAS. It is a view you query rather than a graph you browse, so someone has to build the traversal and the interface.
Does Databricks Unity Catalog capture column level lineage?
Yes, automatically, for queries run on Databricks. The documented limitations are worth knowing before you rely on it: nothing captured before September 1, 2024, lineage is not preserved through renames of catalogs, schemas, tables, views, or columns, and RDDs, global temp views, checkpointed datasets, and user defined functions are not captured. Column lineage also requires both source and target to be referenced by table name rather than by path.
Does BigQuery have column level lineage?
Yes, through Knowledge Catalog, which was renamed from Dataplex Universal Catalog on April 10, 2026. It supports top level columns and has several specific limits: it is not collected for load jobs or routines, external tables get no upstream column lineage, nested fields inside STRUCT or JSON are unsupported, and any job that would create more than 1,500 column level links falls back to table level lineage only.
How is column level lineage generated automatically?
Mostly by parsing SQL. A tool reads the statements the warehouse actually executed from query history, resolves each select, join, and transformation into edges between source and target fields, and layers compiled dbt metadata on top to add modeled intent. Static code analysis parses ETL code directly, which is the only way to see inside stored procedures. Runtime events, the OpenLineage model, have each job report its own inputs and outputs as it runs.
Do I need column level lineage or is table level enough?
Table level lineage is enough if you only need a rough map of what feeds what. Column level lineage becomes worth paying for once you are doing impact analysis under time pressure, deprecating columns without breaking reports, or proving where a specific reported figure came from. A useful test: if your last incident involved reading SQL to work out which dashboards touched the broken field, column level lineage would have replaced that work.
How much does column level lineage cost?
It is usually gated behind a premium tier. dbt requires Enterprise or Enterprise+, Snowflake requires Enterprise Edition, and the commercial catalog vendors including Atlan, Collibra, Alation, Informatica, IBM, Select Star, Secoda, and Coalesce all quote rather than publish. Datafold redirects its pricing page to contact sales. Dataobservability publishes tiers at 99, 299, and 799 dollars a month with column level lineage included on all three.
Can column level lineage cross multiple systems?
Only partly, and this is the main limitation of platform native lineage. Snowflake traces columns inside Snowflake, Unity Catalog inside Databricks, dbt inside the dbt project, so a stack spanning ingestion, warehouse, transformation, and BI ends up with several accurate fragments and no continuous path. Parsing warehouse query history plus dbt metadata joins the largest of those fragments, but transformations that happen inside a BI tool or before load remain outside any warehouse based graph.
More of the platform
Catch broken data before your stakeholders do
Connect your warehouse and get column level data lineage live from one read-only connection. Transparent pricing, no credit card.