BigQuery Lineage Not Showing: View It in the Console and Fix It
Last updated August 2026 · Datatrail
Read-only connection. Datatrail never moves or mutates your data.
To see lineage for a BigQuery table, open the table in the BigQuery console and click the Lineage tab. The default Graph view shows table-level lineage across systems and regions, and clicking a node or an edge reveals the job and the transformation logic behind it. If the tab is empty, the three usual causes are propagation delay, missing permissions, or the retention window: Google's documentation states that lineage can take from 30 minutes up to 24 hours to display, and that all lineage information is retained for only 30 days.
That 30-day figure is the one that catches people out. Snowflake keeps column lineage for a year and Databricks keeps it in Catalog Explorer indefinitely, so it is reasonable to assume BigQuery does something similar. It does not. If the job that built a table ran five weeks ago and has not run since, its lineage is gone, and no amount of checking permissions will bring it back.
How to view lineage for a BigQuery table in the console
The click path is short, and it is the fastest answer for a one-off lookup:
- Go to the BigQuery page in the Google Cloud console.
- Open the table you want lineage for.
- Click the Lineage tab.
- The Graph view opens by default, showing table-level lineage across systems and regions.
- Click Expand next to a node to load further connections.
- Click a node or an edge to open asset details and the transformation process behind it.
Before any of that works, the Data Lineage API has to be enabled in each project where lineage is recorded and in the project where you are viewing it, where you also need the Dataplex API. This is the step most often missed in a multi-project setup, because lineage is recorded in the compute project that ran the job while you are usually looking at the storage project that holds the table.
You also need three roles, and they sit in different places:
roles/datalineage.viewer(Data Lineage Viewer) on the projects where lineage is recorded and viewedroles/bigquery.dataViewer(BigQuery Data Viewer) on the table's storage projectroles/bigquery.resourceViewer(BigQuery Resource Viewer) on the job's compute project
Note that the documentation for all of this now lives under Knowledge Catalog, which is what Dataplex Universal Catalog was renamed to in April 2026. The API names, CLI commands and IAM role names did not change, so older instructions still work even though the product name in the docs is different.
Why is BigQuery not showing my lineage from tables to views?
Work through these in order, cheapest first.
1. It is too soon. Google's own wording is that "depending on the volume and complexity of the data being processed, it can take from standard 30 minutes up to 24 hours for the data lineage to display." If the query ran ten minutes ago, wait. This alone explains a large share of empty Lineage tabs.
2. It is too late. All lineage information is retained for 30 days. Lineage survives the deletion of the source table for that window, but nothing survives past it. A view built once, months ago, from a table that has not been touched since will show nothing, and that is correct behavior rather than a bug.
3. The API is not enabled. It must be on in both the compute project and the project you are viewing from.
4. Permissions. There are three distinct failures here, and each produces a different message. Missing roles/datalineage.viewer gives you "Fetching lineage failed due to missing permissions." Missing bigquery.jobs.get in the compute project gives "You don't have permission to view BigQuery process metadata in project X," which is the one that hides the query behind an edge while still drawing the graph. Missing bigquery.tables.get in the storage project gives "Entry with this fully qualified name is not available in Knowledge Catalog or you do not have permissions to view it."
Those error strings are worth reading literally. The second one in particular looks like missing lineage but is actually missing job metadata, and the fix is a role grant in a different project from the one you are looking at.
5. The job type is not covered. Load jobs and routines do not produce lineage. External tables produce upstream lineage only. If your view sits on top of a federated or external source, the chain will stop rather than continue.
Finding the query that created a table in BigQuery from lineage
This is the most common reason people open the Lineage tab at all, and the answer is that the query is attached to the edge, not the table. In the Graph view, click the edge running into your table, or the process node between two tables. The panel that opens shows the job details and the transformation logic, which is where the originating SQL lives.
If you can see the graph but the process details are blank or throw a permissions message, you are missing bigquery.jobs.get in the project that ran the job. That is the single permission standing between you and the query text.
When lineage has aged out of the 30-day window, fall back to INFORMATION_SCHEMA.JOBS, which is a different system with its own retention (180 days for the by-project view) and which stores the query text directly:
SELECT
creation_time,
user_email,
query
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE destination_table.table_id = 'fct_orders'
AND state = 'DONE'
AND error_result IS NULL
ORDER BY creation_time DESC
LIMIT 10;
This is the more reliable route for "who built this table and how," because it reads the job history directly instead of the derived lineage graph. It will not give you a multi-hop graph, but it will give you the exact SQL.
BigQuery table lineage lookup with the Data Lineage API
For anything repeatable, the console is the wrong tool. The Data Lineage API exposes two methods that matter: searchLinks, which returns the links into or out of a given asset, and batchSearchLinkProcesses, which maps those links back to the jobs that produced them. Together they answer the programmatic version of both questions above, and they are what you would use to build a nightly export of your lineage graph.
Two console limits apply when you traverse: a maximum depth of 20 levels, and a maximum of 10,000 links per direction. Large graphs are truncated at those boundaries.
What BigQuery lineage does not capture
The gaps are specific and worth knowing before you trust a graph as a complete picture:
- Column-level lineage degrades silently. A job that creates more than 1,500 column links reverts to table-level lineage only. You are not told; the graph simply gets coarser.
- Nested fields are invisible. Column lineage covers top-level columns. Fields inside
STRUCTandJSONtypes are not tracked. - Partitioning pseudo-columns are not recognized, including
_PARTITIONDATEand_PARTITIONTIME. - Load jobs and routines produce no lineage, and external tables give upstream only.
- It stops at the edge of Google Cloud. A table feeding a Looker dashboard, a Power BI dataset or a reverse ETL sync has no downstream links, because nothing outside BigQuery is recorded.
That last point compounds with ingestion. Rows that arrive from outside the warehouse, say from a third-party API or from a scraping pipeline that turns web pages into clean structured data, land through a load job, and load jobs produce no lineage at all. The table appears in the graph with nothing upstream of it, which reads as a root source even though it is not.
When to move past native BigQuery lineage
Native lineage is free, requires no agent, and is a reasonable answer to "what fed this table last month." It struggles with three things: the 30-day window, the silent fallback to table-level on wide jobs, and the hard stop at the BigQuery boundary. If your actual question is "what breaks if I change this column," those three limits tend to be exactly the ones in the way, because the dashboards and downstream models you care about are usually on the other side of that boundary.
Datatrail parses query history and your dbt manifest into persistent column-level lineage that does not expire after 30 days, follows data past the dbt boundary into ad hoc SQL, and computes downstream impact before you merge a change. It connects read-only. For the architectural view of how lineage works in BigQuery, see our BigQuery data lineage guide, the BigQuery lineage use case, and the equivalent walkthrough for Snowflake column-level lineage. If you are choosing a tool, our comparison of data lineage tools covers the field.
See how your data flows, end to end
Connect your warehouse read-only and map lineage, freshness, and downstream impact before a change breaks a dashboard. Planned transparent pricing, no card to start.