Skip to content
WildRun AI home Get Your Free Audit
AI SEO & GEO · 2026-06-12 (updated 2026-09-27) · 12 min read · WildRun AI

Google Search Console BigQuery Export: Complete 2026 Guide

How to set up the Google Search Console BigQuery export, what the three tables hold, the anonymized-query limit it will not fix, and how to catch a broken export in time.

Vintage globe with golden wrench and silver gear on blue Earth

If you manage a website's SEO and rely on Google Search Console's standard interface, you are working with a filtered view of your own data. Search Console's own export caps out at 1,000 rows, its Search Analytics API returns a maximum of 25,000 rows per request and tops out at 50,000 rows per day per site per search type, and the whole dataset is trimmed to the last 16 months, per Google's deep dive into performance data filtering and limits, the Search Analytics API reference and About Search Console data. The bulk data export to Google BigQuery removes the row cap, extends your storage window as far forward as you keep it running, and opens a SQL interface that answers questions the dashboard cannot.

This guide covers what the export actually includes, how the three core tables work, what setup requires, how to keep query costs under control, how to catch a broken export before it costs you a month of data, and where the approach falls short. The goal is to help you decide whether it's worth the effort — not to convince you it always is.

What the bulk data export actually gives you

Google launched the Search Console bulk data export in February 2023. Once configured, it sends a daily export of your property's search performance data to a BigQuery dataset inside your own Google Cloud project. You own the dataset; Google just writes to it.

The defining advantage over every other export path is no row limit. Where the interface stops at 1,000 rows and the API at 25,000 per request, the bulk export sends the rows Search Console holds for each day — every query, every page URL, every country and device combination. For sites with large keyword footprints, this is the most complete organic search dataset Google hands out.

What it does not give you: real-time data, retroactive history, or a fix for anonymized queries. Data is exported once per day. The export starts from the day you configure it — Google's setup documentation is explicit that the first export covers the day of the export itself, and points you to the API or the in-product reports if you want history that precedes your setup. And the anonymized query problem (more on this below) follows you into BigQuery, because Google's overview of the bulk data export states that what gets exported is your performance data excluding anonymized queries.

The three tables you need to understand

Every bulk data export populates three tables in your BigQuery dataset, documented in Google's table guidelines and reference. Knowing which table answers which question saves time and keeps query costs predictable.

searchdata_site_impression

This table aggregates data at the property level: query, country, search type and device, with no page URL dimension. It's the right starting point for keyword trend analysis, CTR benchmarking, and understanding which query categories drive traffic over time.

Core columns: query, country, device, search_type, data_date, impressions, clicks and sum_top_position. Average position is not stored directly — you derive it by dividing sum_top_position by impressions and adding 1, as Google's query guidelines and sample queries demonstrate. This is the cheaper table to query and should be your default.

searchdata_url_impression

This table aggregates by URL, which gives you the detailed view of which queries hit which pages, plus the rich-result and appearance flags — fields such as is_amp_top_stories, is_job_listing and is_review_snippet — that let you segment performance by result type. It is the table you use to answer "which pages rank for which queries" or "how does this rich result type affect CTR."

It is also substantially larger than the site-level table and can get expensive to query without filtering. Always add a WHERE data_date >= clause. Scanning the full table without a date filter on a busy site processes the whole partition set in a single run.

ExportLog

A lightweight record of what data was saved each day. It is not for analysis, but it is the first place to look when your data seems to have a gap — and there is one detail that matters more than any other: per Google's table reference, failed exports are not recorded in ExportLog at all. A missing date is the failure signal. ExportLog will never tell you why a day failed, so treat an absent row as "investigate," not as a query bug.

Setting up the export: the exact steps

Setup requires actions in two separate Google products, and you must be a property owner in Search Console to start or stop a bulk data export. Both sides must be complete before data flows.

Google Cloud side

Create a Google Cloud project and enable billing. BigQuery needs an active billing account even to receive the export. Then enable the BigQuery API from the API library.

Next, grant the Search Console export service account permission to write to your project. Add search-console-data-export@system.gserviceaccount.com as a principal with two IAM roles: BigQuery Job User (bigquery.jobUser) and BigQuery Data Editor (bigquery.dataEditor). Missing either role is the single most common reason a new export fails with a permissions error.

Search Console side

In Search Console, open Settings → Bulk data export, enter your Google Cloud project ID, choose a dataset location, and confirm. Pick a location close to where you will run queries; the location is set once and the dataset is created for you.

Setup itself takes well under an hour, most of it in the Cloud console. After that there is nothing to do but wait for the first daily export to land.

Monitoring the export and troubleshooting failures

This is not "configure once and forget." Google's guidance on managing and monitoring bulk data exports describes the retry behaviour precisely: when a non-transient error interrupts an export — a permissions change, for example — Search Console does not retry immediately. It waits for the next day's scheduled export and includes the data it missed, and it keeps retrying a missed day for about a week before giving up on that day permanently.

That week is your entire margin for error. A one-day blip costs you nothing. A misconfiguration you notice three weeks later costs you every day beyond the retry window, and no amount of fixing brings those dates back, because the export is not retroactive.

Two habits close the gap. First, check the Bulk data export settings page inside Search Console, which is where export errors actually surface — not BigQuery, and not ExportLog, which by design holds only successes. Second, run a standing check for missing dates in your own dataset. A three-line query against ExportLog that counts distinct dates in the last 30 days, scheduled weekly, catches a stalled pipeline inside the retry window instead of after it:

SELECT
  MAX(data_date) AS latest_date,
  DATE_DIFF(CURRENT_DATE(), MAX(data_date), DAY) AS days_behind
FROM `your_project.searchconsole.ExportLog`;

If days_behind creeps past two or three, go look at the settings page. After fixing a configuration problem, Search Console's Test report button confirms project access and permissions immediately, but it does not trigger a new export — you still need to check back the next day to confirm the scheduled export succeeded.

The anonymized query problem — set honest expectations here

This is the limitation most guides undersell, and the one most likely to make the whole project disappointing.

Google withholds queries that are too rare to report without risking user privacy. Its documentation defines an anonymized query as one that is not issued by more than a few dozen users over a two-to-three month period. In the interface, those queries are omitted from the query tables but still counted in the chart totals — which is exactly why the numbers in your keyword table never add up to the numbers on your graph.

The BigQuery export does not recover them. Google's own overview of the feature describes the exported data as your performance data excluding anonymized queries. If your reason for setting this up is to finally see the hidden keywords Search Console won't show you, stop here: that data is not in the export, and no SQL query will conjure it.

The practical consequence scales inversely with traffic. A site with a handful of clicks per day across a long tail of specific, local, low-volume searches will find a large share of its clicks attached to queries that simply are not named anywhere in the dataset. A business serving a defined regional market — a contractor in Redmond, a clinic in Bend, a shop in Sisters — is squarely in that category, because the individual searches that bring in its customers are naturally low-volume nationwide. Model that before investing a weekend in the setup.

Your first two useful SQL queries

Once data starts arriving, these two queries give immediate signal. Both use the site-level table to keep costs down. Replace your_project with your Google Cloud project ID.

Top queries by clicks — last 30 days

SELECT
  query,
  SUM(clicks)       AS total_clicks,
  SUM(impressions)  AS total_impressions,
  ROUND(SUM(clicks) / NULLIF(SUM(impressions), 0) * 100, 2) AS ctr_pct,
  ROUND((SUM(sum_top_position) / SUM(impressions)) + 1.0, 1) AS avg_position
FROM `your_project.searchconsole.searchdata_site_impression`
WHERE data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
  AND search_type = 'WEB'
GROUP BY query
ORDER BY total_clicks DESC
LIMIT 100;

Month-over-month click trend by search type

SELECT
  search_type,
  DATE_TRUNC(data_date, MONTH) AS month,
  SUM(clicks)       AS monthly_clicks,
  SUM(impressions)  AS monthly_impressions
FROM `your_project.searchconsole.searchdata_site_impression`
WHERE data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH)
GROUP BY 1, 2
ORDER BY 2 DESC, 3 DESC;

For visualization, connect Looker Studio directly to the BigQuery dataset rather than exporting to Sheets. That avoids size limits and keeps dashboards current without manual refreshes.

Where AI visibility now gets measured instead

Earlier versions of this guide suggested slicing the export by search appearance to isolate AI Overview performance. That workaround is no longer the best route, because Google shipped a dedicated report. Search Console's Search generative AI performance reports break out impressions and clicks from generative AI features such as AI Overviews and AI Mode, with a companion report for Discover; Google finished rolling them out to all sites on August 31, 2026, and the report documentation covers how to segment them by page, device and country.

Use the reports for the AI question and the export for what the reports can't do: unlimited rows, arbitrary SQL, and a history longer than 16 months that you control. The strategic context for why AI placement matters at all is in our guide to ranking in Google AI Overviews, and the measurement side across assistants is in tracking whether AI engines cite your brand.

Querying efficiently: partitioning and avoiding surprise bills

Both impression tables are partitioned by data_date. That structure only saves money if your queries use it — a query without a date filter forces BigQuery to scan every partition. Four habits keep costs predictable, and Google's guide to estimating and controlling BigQuery costs covers the mechanics behind them.

Filter on data_date first. Every query should carry a WHERE data_date >= ... clause before any other condition. It is the single biggest cost lever you have.

Never SELECT *. On-demand BigQuery charges by bytes processed, and it reads column by column. Pulling every column from the URL-level table, which carries dozens of dimension and metric fields, costs far more than naming the five or six you need.

Check the estimated bytes processed before running. The BigQuery console shows an estimate as you type, before you click Run. For anything touching the URL-level table, glance at that number first; if it looks large, add a filter and check again.

Remember rows are not pre-aggregated. Google's table reference does not promise one row per query-and-URL combination per day. Always wrap metrics in SUM() and GROUP BY the dimensions you care about — treating a raw row count as a metric will overstate your numbers.

What BigQuery actually costs for this use case

The Search Console bulk data export is free. BigQuery charges for storage and for query processing, and the BigQuery pricing page is the only figure worth trusting, because the rates change — check it rather than any number printed in an article, including this one.

What is durable is the shape of the bill. Storage is metered per GiB with the first 10 GiB free each month, prorated rather than billed in blocks, and data left unmodified for 90 consecutive days moves to long-term storage at half the active rate. Queries on the on-demand model are billed on bytes processed, with the first 1 TiB of query data processed each month free.

For a single small or mid-size property, that combination usually means the dataset sits inside or near the free storage tier for a long time, and ordinary analysis queries against the site-impression table stay inside the free processing tier. The way this becomes a real bill is an unfiltered scan of the URL-level table, repeated. Scope your date range first and the cost question mostly disappears. If you want a hard ceiling on storage, set partition expiration on the dataset so partitions older than your chosen threshold are deleted automatically.

When this is NOT the right solution

Your site gets very few clicks per day. At low volume, anonymized queries dominate, and you will maintain infrastructure to study a dataset where a large share of the clicks have no query attached. The standard interface gives you equivalent signal with no setup.

You need data from before your setup date. The export is not retroactive and there is no backfill. Google's own answer is to use the API or the in-product reports for pre-setup history, and the API's row caps apply there — so large sites will still see an incomplete picture of the past. Third-party connectors such as Supermetrics pull history through the same API and inherit the same limits.

No one on your team writes SQL. The value is entirely in what you ask. Looker Studio gives non-SQL users a visual layer, but segmenting by arbitrary dimensions, deriving metrics and joining to other sources all need someone who can write queries.

You want an out-of-the-box SEO dashboard. Tools like Semrush and Ahrefs deliver competitive intelligence, rank tracking and pre-built reporting with no infrastructure. If the goal is weekly monitoring rather than a data pipeline, start there.

Making it work once the data is flowing

The teams that get durable value from this treat it as infrastructure, not a report. You configure it once, let it accumulate consistent daily data, and query it when a specific question comes up: did the migration hurt mobile CTR? Which informational queries draw impressions but no conversions? Which pages have been sliding for their target queries over six months?

The real payoff comes from joining Search Console data to your own first-party records — your CRM, booking system or call log. Search data tells you what people searched; your records tell you what that search actually produced.

A concrete join: Search Console and GA4 in the same query

If your GA4 property also has its BigQuery export enabled, both datasets live in tables you control, which means a direct SQL join instead of reconciling two exports in a spreadsheet. Match Search Console's data_date against GA4's daily event tables:

SELECT
  s.query,
  s.data_date,
  SUM(s.clicks)      AS gsc_clicks,
  SUM(s.impressions) AS gsc_impressions,
  COUNT(DISTINCT g.user_pseudo_id) AS ga4_sessions
FROM `your_project.searchconsole.searchdata_site_impression` s
LEFT JOIN `your_project.analytics_XXXXXXXX.events_*` g
  ON PARSE_DATE('%Y%m%d', g._TABLE_SUFFIX) = s.data_date
  AND g.event_name = 'session_start'
WHERE s.data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY 1, 2
ORDER BY gsc_clicks DESC;

Note what this join is and is not. Joining on date alone associates daily totals, not individual sessions to individual queries — Google does not pass the query through to GA4. It is a useful daily-trend comparison, not user-level attribution, and reading it as the latter is a common way to draw a confident wrong conclusion.

How customers actually find a business like yours now

Row-level search data is only worth collecting if you know which surfaces it represents. For a business serving Bend, Redmond, Sisters, Sunriver or anywhere else in Central Oregon, three of them matter, and Search Console sees them differently.

Classic organic results are what most of this dataset describes. The map pack largely is not — local pack visibility is driven by your Google Business Profile, proximity and reviews, and it is reported separately from your website's search performance, which is why a strong organic keyword table can coexist with an invisible map presence. And AI assistants are a third surface again: Google's generative AI features now report inside Search Console, while citations in ChatGPT, Perplexity and other assistants show up in none of it — those you have to check deliberately.

If you want the local side in order first, our guide to local SEO in Bend covers what actually moves the map pack, and SEO vs AEO vs GEO lays out how the measurement frameworks differ across each channel. If you'd rather see where you currently stand across all three before building any pipeline, WildRun AI's free visibility audit reports on what's showing up today in Google, the map pack and AI answers.

Frequently asked questions

Does the Google Search Console BigQuery export include anonymized queries?

No. Google's overview of the bulk data export describes the exported data as your performance data excluding anonymized queries, so the export contains the same gap the interface does. Google's documentation defines an anonymized query as one not issued by more than a few dozen users over a two-to-three month period. In the Search Console interface those queries are left out of the query tables but still counted in chart totals, which is why your keyword table never sums to your graph. BigQuery does not fix this.

How far back does the BigQuery export go?

It is not retroactive. Google's setup documentation states the first export covers the day of the export itself, and points you to the Search Console API or the in-product reports for anything earlier. Search Console holds the last 16 months of data in its own interface, and none of that is backfilled into BigQuery. You only have the history you started collecting.

What does the Google Search Console BigQuery export cost?

The export itself is free; BigQuery bills for storage and query processing. Per Google Cloud's BigQuery pricing page, storage is metered per GiB with the first 10 GiB free each month and drops to half price once data has gone 90 consecutive days without modification, and on-demand queries are billed on bytes processed with the first 1 TiB per month free. For a single small or mid-size property that usually means little or nothing, with one exception: repeated unfiltered scans of the URL-level table. Check the pricing page for current rates rather than trusting a figure in an article.

What is the difference between searchdata_site_impression and searchdata_url_impression?

Per Google's table reference, searchdata_site_impression aggregates at the property level by query, country, search type and device, with no page URL. It is the cheaper table and the right starting point for keyword analysis. searchdata_url_impression aggregates by URL, adding the page dimension and the rich-result appearance flags, which makes it far larger and more expensive to query. Always filter it by data_date.

How do I know if my export has stopped working?

Watch for missing dates, not error rows. Google's table reference notes that failed exports are not recorded in ExportLog at all, so a gap in dates is the only signal the dataset gives you. Export errors surface on the Bulk data export settings page inside Search Console. This matters because Search Console retries a missed day for about a week and then stops keeping that day's data for good, so a problem you find within the week costs you nothing and one you find a month later is permanent.

How often does Search Console data arrive in BigQuery?

Once per day, for as long as the export runs. There is no real-time or intraday refresh, so if you need same-day data the bulk export is not the right tool.

Can I use the BigQuery export to measure AI Overviews performance?

There is now a better route. Search Console's Search generative AI performance reports break out impressions and clicks from generative AI features such as AI Overviews and AI Mode, and Google completed the rollout to all sites on August 31, 2026. Use those reports for the AI question and the BigQuery export for what they cannot do: unlimited rows, arbitrary SQL and history beyond 16 months. Neither one covers citations in non-Google assistants like ChatGPT or Perplexity.

Do I need SQL skills to use the BigQuery export?

Yes, for anything beyond the basics. Setup is a short configuration job, but querying, segmenting and joining the data all require SQL. Looker Studio can connect to the dataset for visual dashboards, which covers reporting for non-SQL users, but custom analysis needs someone who can write queries.

Is your business showing up in AI answers?

Request a free review of your Google, Maps, website and AI-search visibility from WildRun, an SEO, AEO and GEO studio in Bend, Oregon.

Get Your Free Visibility Audit