Skip to content
Free AI visibility check: does your brand show up in ChatGPT and Gemini answers?Apply →

GA4 BigQuery export guide: setup, costs and first queries

How to send GA4's raw event data to BigQuery: setup steps, limits for standard properties, the sandbox and prices as of October 2026, the table schema, first SQL queries, joining CRM data, and a note on Türkiye's data protection law.

AuthorSemih BayındırReviewed byLast updated: View as Markdown
GA4 BigQuery export guide: the GA4 and BigQuery logos

The GA4 interface answers most day-to-day questions. But questions like "which campaign's leads turned into revenue?", "how does this period compare with last year, event by event?" or "why do GA4 and the CRM count differently?" need raw data. GA4's BigQuery export moves that raw data into BigQuery, Google's data warehouse. This guide covers the setup, the limits, costs as of October 2026, the table schema, first queries and joining CRM data.

Why export to BigQuery?

According to Google's help page, the export sends all the raw, unsampled event data GA4 receives to BigQuery, and the exported data is yours, with access managed through BigQuery permissions. The practical gains:

  • Retention: on standard GA4 properties, event data retention can be set to at most 14 months, and that setting governs explorations and funnel reports. Data in BigQuery stays until you delete it.
  • Joins: you can combine GA4 data with CRM, ad spend and revenue data in one place.
  • Reporting: Looker Studio dashboards can read from BigQuery instead of running into GA4 API quotas. See what Looker Studio is for the details.

One caveat: Google says BigQuery data excludes the modelling and similar additions GA4 applies in its reports, so BigQuery and the GA4 interface will not always match exactly.

Export types and limits

TypeAvailable onWhen data arrivesLimit
DailyStandard and 360Full data for the previous day, typically mid-afternoon in the property's time zoneStandard: 1 million events a day. 360: 20 billion events a day
StreamingStandard and 360Current-day data within minutesNo volume limit; no completeness guarantee
Fresh Daily360 onlyBatched updates through the dayOnly "Normal" and "Large" 360 properties

Details worth knowing:

  • The 1 million event limit. If a standard property keeps exceeding it, the daily export is paused and earlier days are not reprocessed. Properties that exceed it by a wide margin may be paused right away. The fix is to exclude data streams and unneeded events in the link settings.
  • Streaming leaves out traffic source data for new users. Google recommends the daily export for user attribution data.
  • Late events. Daily tables can be updated for a few days with events that arrive late. Treat the last three days as provisional.
  • No backfill, no re-export. The export runs from the moment you link; Google says exported data cannot be re-exported.

Costs: sandbox, free tier and prices

The link itself is free on the GA4 side; the cost is in BigQuery. The figures below are those shown on Google Cloud's BigQuery pricing page as of October 2026, in US dollars, for the page's default region, Iowa (us-central1). They can differ by region.

ItemAs of October 2026
Queries (on-demand)First 1 TiB free each month; then US$6.25 per TiB
Active logical storageUS$0.000031507 per GiB-hour; first 10 GiB free each month
Long-term logical storage (tables unchanged for 90 days)US$0.000021918 per GiB-hour; first 10 GiB free each month
GA4 streaming exportUS$0.05 per GB (GA4 help page; 1 GB is roughly 600,000 events)

The BigQuery sandbox works without a credit card or billing account. Google's sandbox docs list its limits: a lifetime limit of 10 GiB of storage (not refunded when you delete data), 1 TiB of queries a month, all tables and partitions expiring after 60 days, and no streaming. For the GA4 export that makes the sandbox fine for a trial but not for lasting history: daily tables older than 60 days disappear. Google's setup page also warns that moving from the sandbox to paid can cause export failures if the project is already over 10 GB.

The most effective way to keep costs down is to write queries carefully. BigQuery charges by the columns you read, so selecting only the columns you need instead of SELECT *, and narrowing the date range with _TABLE_SUFFIX, cuts the data scanned sharply.

Setup, step by step

Google's setup docs describe three stages:

  1. Create a Google Cloud project and enable the BigQuery API.
  2. Prepare the project: start with the sandbox or attach a billing account. Google notes that the export needs a valid payment method to continue, and days interrupted by a payment problem cannot be re-exported.
  3. Link GA4: in GA4 go to Admin > Product links > BigQuery links > Link. Choose the project and the data location, pick the data streams to export and the events to exclude, tick Daily, Streaming or both, and submit.

Permissions: at least the Editor role on the GA4 property, and an email address with Owner access to the BigQuery project. Data should start arriving within 24 hours of linking.

Choose the location carefully. The data location is set during linking if the project has no dataset for the property yet. Changing it later means deleting the link, backing up the data and recreating the dataset, and can leave a gap in the data; Google suggests cross-region dataset replication as an alternative. As of October 2026 BigQuery's location list has no region in Türkiye; more on that in the data protection section below.

Schema: tables and fields

Each property gets a dataset named analytics_<property_id> in the project. Inside it:

  • events_YYYYMMDD: the full daily table from the daily export.
  • events_intraday_YYYYMMDD: the streaming export's intraday table, deleted once the daily table is complete.

Each row is one event. Common fields: event_date, event_timestamp (microseconds, UTC), event_name, user_pseudo_id (a pseudonymous user ID), user_id (if you send one), event_params (event parameters, a repeated RECORD), collected_traffic_source (UTM values collected with the event) and session_traffic_source_last_click (the session's last-click source). Because parameters are nested, queries use UNNEST.

First queries

In the examples below, replace project.analytics_123456789 with your own project and dataset.

Daily events and users:

SELECT
  event_date,
  COUNT(*) AS events,
  COUNT(DISTINCT user_pseudo_id) AS users
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261007'
GROUP BY event_date
ORDER BY event_date;

Leads by source and medium (change generate_lead if your lead event has a different name):

SELECT
  session_traffic_source_last_click.manual_campaign.source AS source,
  session_traffic_source_last_click.manual_campaign.medium AS medium,
  COUNT(*) AS leads
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261031'
  AND event_name = 'generate_lead'
GROUP BY source, medium
ORDER BY leads DESC;

Reading a parameter (the page the lead came from):

SELECT
  (SELECT value.string_value FROM UNNEST(event_params)
   WHERE key = 'page_location') AS page,
  COUNT(*) AS leads
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261031'
  AND event_name = 'generate_lead'
GROUP BY page
ORDER BY leads DESC;

Before running a query, check the "this query will process X MB" estimate in the top right of the BigQuery editor; you see the cost before you pay it.

Joining CRM data

This is where the real value is. GA4 knows which campaign a lead came from; the CRM knows whether that lead was qualified and whether it closed. Joining them needs a shared key.

The method we recommend:

  1. Generate a random lead ID (a UUID, for example) when the form is submitted.
  2. Write it both to the CRM record and, as a parameter (lead_id), to the GA4 generate_lead event. For the tagging side, see what Google Tag Manager is.
  3. Load the CRM's lead table (ID, stage, deal value) into BigQuery on a schedule.
  4. Join the two tables on lead_id.
WITH ga4_leads AS (
  SELECT
    (SELECT value.string_value FROM UNNEST(event_params)
     WHERE key = 'lead_id') AS lead_id,
    session_traffic_source_last_click.manual_campaign.campaign_name AS campaign
  FROM `project.analytics_123456789.events_*`
  WHERE _TABLE_SUFFIX BETWEEN '20260701' AND '20260930'
    AND event_name = 'generate_lead'
)
SELECT
  g.campaign,
  COUNT(*) AS leads,
  COUNTIF(c.stage = 'qualified') AS qualified_leads,
  SUM(c.deal_value) AS won_value
FROM ga4_leads g
LEFT JOIN `project.crm.leads` c USING (lead_id)
GROUP BY g.campaign
ORDER BY won_value DESC;

Do not use an email address or phone number as the join key, and do not send them to GA4: Google Analytics policies do not allow personally identifiable information to be sent. A technical ID is both safer and enough. We build this whole set-up as our marketing data warehouse service.

A note on KVKK: data location and transfers abroad

BigQuery has no region in Türkiye, so for a Turkish company any location chosen for the GA4 export is abroad. If the exported data includes user_pseudo_id, user_id or IDs from the CRM, review with your counsel whether these count as personal data and on what basis they are transferred.

The rule on transfers abroad is Article 9 of Law No. 6698 on the Protection of Personal Data (KVKK), as rewritten by Article 34 of Law No. 7499 (Official Gazette, 12 March 2024, issue 32487). In outline:

  • KVKK Art. 9(1): personal data may be transferred abroad if one of the conditions in Articles 5 and 6 applies and there is an adequacy decision for the destination country, sector or international organisation.
  • KVKK Art. 9(4): without an adequacy decision, data may be transferred with one of the listed appropriate safeguards, provided a condition in Articles 5 and 6 applies and the data subject can exercise their rights in the destination country; one safeguard is the standard contract announced by the Board (Art. 9(4)(c)).
  • KVKK Art. 9(5): a standard contract must be notified to the Authority by the controller or processor within five working days of signing.
  • KVKK Art. 9(6): with neither an adequacy decision nor a safeguard, transfers are allowed only occasionally, in one of the listed cases (for example, explicit consent after being informed of the risks).

On the technical side, the most effective step is data minimisation: send no personal data to GA4, exclude unneeded events from the export, limit BigQuery access by role, and set a retention period. Google notes that when Consent Mode is in place, cookieless pings also appear in the export.

How Roicool works on this

As part of GA4 consulting we switch on the export, tune event volume to the 1 million limit and set up the first queries; the CRM join and the reporting layer are part of a marketing data warehouse project. For measurement as a whole, see our analytics consulting page. How GA4 differs from product analytics tools is covered in our GA4 vs Mixpanel comparison.

Sources

Frequently asked questions

Is the GA4 BigQuery export free?

GA4 does not charge for the link itself; the cost sits on the BigQuery side. As of October 2026 the first 10 GiB of storage and the first 1 TiB of query processing each month are free; beyond that, on-demand queries cost US$6.25 per TiB (Iowa region). Streaming export adds US$0.05 per GB.

Can we export historical GA4 data to BigQuery?

No. The export sends data from the moment you create the link; there is no backfill. Google also says data cannot be re-exported once it has been exported. If you are likely to need BigQuery later, switching the link on today is the cheapest option.

What happens if a standard GA4 property passes 1 million events a day?

The daily export is limited to 1 million events per day on standard properties. If a property keeps exceeding it, the daily export is paused and earlier days are not reprocessed. The fixes are to cut volume with data stream and event exclusion filters, use the streaming export, or move to Analytics 360.

Can we use the BigQuery sandbox for the GA4 export?

Yes, within its limits. The sandbox has a lifetime limit of 10 GiB of storage that is not refunded when you delete data, tables expire after 60 days, and streaming is not supported. It is fine for a trial; for lasting history you need to attach a billing account.

How do we match GA4 data with CRM data?

The safest way is to add a technical lead ID, created when the form is submitted and also written to the CRM, as a parameter on the GA4 event. In BigQuery the two tables join on that ID. Do not send personal data such as emails or phone numbers to GA4; Google's policies do not allow it either.

Which region should the data live in?

The location is chosen when you create the link and is a chore to change later. As of October 2026 BigQuery's location list has no region in Türkiye, so for a Turkish company any location is abroad. Review personal data transfers under Article 9 of KVKK, Türkiye's data protection law, with your counsel and keep the exported data to a minimum.

Sources

  1. 1Google Cloud, BigQuery pricing, 2026
  2. 2Google Cloud, Try BigQuery using the sandbox, 2026
  3. 3Google Cloud, BigQuery locations, 2026
  4. 4Google Analytics Help, BigQuery Export, 2026
  5. 5Google Analytics Help, Set up BigQuery Export, 2026
  6. 6Google Analytics Help, BigQuery Export schema, 2026
  7. 7Google Analytics Help, Data retention, 2026
  8. 8Google Analytics Help, Best practices to avoid sending PII, 2026
  9. 9Law No. 7499, Art. 34 (KVKK Art. 9), Official Gazette 12.03.2024, issue 32487, 2024

About the author

Managing Partner

Co-founder of Roicool. Before founding Roicool, Mahmud had already worked with more than 15 clinics; today Mahmud leads the performance marketing, Google Ads, SEO and measurement work.

All their posts

The service this post relates toData and measurementGA4, Google Tag Manager, server-side tagging, Consent Mode, a data warehouse and reporting: ad and sales decisions on data you can trust.

More posts

All Analytics and Data posts

Let’s put what you read to work for you.

In a 30-minute intro we look at your account and tell you which step should come first.