Google Analytics 4 logo

Web analytics

Connect Google Analytics 4 to Excel, Sheets and AI

GA4 event and traffic data as SQL. Pair it with Search Console and your product database without a BigQuery export round-trip.

1connection
0inbound ports
read-onlyenforced

One connection, every surface

Where your GA4 data can go

Connect GA4 once and the same read-only connection feeds all of these — no second setup, no second copy of the data. 8 of 11 have a step-by-step guide.

Guide

GA4 to Excel

Microsoft Excel · Excel add-in

Pull live GA4 results straight into a worksheet and refresh them on demand — desktop Excel, Excel Online, Microsoft 365.

Read the guide
Guide

GA4 to Google Sheets

Sheets add-on

Run a saved GA4 query from the sidebar and drop the rows into the sheet. Shared collaborators can refresh it themselves.

Read the guide
Guide

GA4 MCP server

Claude, Cursor and MCP clients

Give an AI assistant read-only access to GA4 with the schema it needs to write correct SQL — no credentials in the chat.

Read the guide
Supported

GA4 REST API

HTTP endpoint

Publish a GA4 query as an authenticated JSON endpoint any application can call, with an OpenAPI 3.1 spec and ready-made Postman, Insomnia and Hoppscotch collections. No database port is opened.

How REST API works no GA4 walkthrough written yet
Guide

GA4 to Airtable

Automation platform

Sync GA4 rows into an Airtable base on a schedule, or fetch them inside an Airtable automation script.

Read the guide
Guide

GA4 to Baserow

Automation platform

Feed a Baserow table from GA4 over the REST endpoint — self-hosted or Baserow cloud.

Read the guide
Guide

GA4 to SeaTable

Automation platform

Keep a SeaTable base current with GA4 data without exporting a file or exposing the database.

Read the guide
Guide

GA4 to Smartsheet

Automation platform

Push GA4 results into a Smartsheet grid so plans and reports read from the source system, not last week's export.

Read the guide
Guide

GA4 to Anvil

Anvil Works · App platform

Back an Anvil Python app with GA4 through the REST endpoint instead of embedding database credentials in the app.

Read the guide
Supported

GA4 to Power BI

Power Query M

Paste the generated Power Query M into the Power BI Advanced Editor and the report reads live GA4 results over HTTPS — no ODBC driver, no database port opened.

How Power BI works no GA4 walkthrough written yet
Supported

GA4 alerts and reports

Slack · Discord · Email · Webhook

Put a GA4 query on a schedule and have the rows delivered to Slack, Discord, email or a signed webhook — or hold the message until a row count, threshold or percentage change crosses the line you set.

How alerts and reports work no GA4 walkthrough written yet

How it works

5 steps, no inbound firewall change

01

Create a Google service account and grant it read access to the GA4 property.

02

Install the Network Agent and give it the service account key and the numeric property id. The key stays on the agent.

03

Choose which of the 9 tables to sync. Traffic overview, traffic sources, page views and events are on by default.

04

Write ordinary SQL against ga4.traffic_sources, ga4.page_views and the rest — or let Nova write it.

05

Read it from Excel, Sheets, Power BI, MCP or REST, joined to whatever holds your signups and revenue.

Feature deep-dive

What GA4 gives you

Without the BigQuery detour

The usual way to get GA4 into SQL is to link a BigQuery project, wait for the export to start, pay for storage and then query a nested event table. This skips all of it.

  • Data comes from GA4's own reporting API, so there is no export to configure and nothing to wait for.
  • It reads back to GA4's launch in October 2020 on first sync, so the history is there rather than starting from the day you set it up.
  • Rows arrive as day-grain aggregates with named columns — date, source, medium, campaign, channel, sessions, users, engagement rate — rather than as nested event blobs you have to unnest.
  • The complete API response is kept alongside in a raw_data JSON column.

The 9 tables

  • Traffic — traffic_overview, traffic_sources, page_views, user_engagement.
  • Audience — geographic_data, events.
  • Commerce — ecommerce_overview, transactions.
  • Now — realtime_active_users.

Two clocks, and which table runs on which

GA4 has a batch side and a realtime side, and they behave differently. Being clear about it is the difference between a report you trust and one you argue with.

  • The eight batch tables run to yesterday. GA4 does not finalise a day's figures for a day or two, so each incremental pass re-reads the previous three days and lets the numbers settle rather than freezing the first version it saw.
  • realtime_active_users is genuinely live — a rolling thirty-minute window, refreshed on demand when a query touches it, with a thirty-second freshness window.
  • That table is a snapshot, not a history: it answers who is on the site now, not who was on it at four o'clock yesterday.

Shared by every API connector

How every API connector works

  • Your account becomes tables — endpoints are mapped to typed SQL tables with primary keys and indexes, so you write SELECT, JOIN and GROUP BY instead of paging through JSON.
  • You choose what syncs, and how often — each table has its own interval, or none at all. Where the vendor's API supports it, only records that changed since the last run are fetched.
  • The copy is yours — it lives in an AES-256-GCM encrypted DuckDB file next to the agent, on your machine. Not in our cloud.
  • The vendor only ever hears from you — the agent calls the API directly from your own network, so your token is not needed by Query Streams to answer a query.

Good to know

  • It is a synced copy, not a live proxy — a query reads what has already been fetched, so it returns at SQL speed and never spends your API rate limit. Selected tables can additionally refresh a stale row as you read it.
  • Rate limits are respected for you — each connector paces itself well inside the vendor's published limits, so a report cannot get your account throttled for everything else that uses it.
  • Nothing is thrown away — fields the table does not name are kept in a raw_data JSON column you can still query.
  • Join it to your databases — an API table and a SQL Server table in the same statement is an ordinary query here, not an integration project.

Cross-source SQL

Join GA4 to the rest of your data

GA4 knows which source the session came from and nothing about what it was worth. Your database knows the account and your payment processor knows the money. One statement can put the three side by side. Each source runs only the part it can, streams the result back, and the join happens centrally — the sources never talk to each other and nothing is copied anywhere.

3 connections · 3 agents

Google Analytics 4 Web analytics
PostgreSQL Relational engine
Stripe Payments & billing

One statement

-- sessions from GA4, the account from your database, revenue from Stripe
SELECT   g.session_source, SUM(g.sessions) AS sessions, SUM(i.amount_due) AS invoiced
FROM     ga4_site.ga4.traffic_sources1 g
JOIN     pg_crm.public.customers2      c ON c.utm_source = g.session_source
JOIN     billing.stripe.invoices3      i ON i.customer = c.stripe_id
GROUP BY g.session_source
ORDER BY invoiced DESC;

The three parts are connection, schema and table — and the connection name is whatever you called it. Illustrative columns; your tables will be your tables. Batch GA4 tables run to yesterday, so the newest day in a report like this is the day before today — that is GA4’s own finalisation window, not a sync delay. Read-only applies to every piece: SELECT, WITH and EXPLAIN only, with a ceiling on how much any one source may hand over for a single query. How federated queries work

Connection details

What GA4 needs

Authentication
A Google service account key with read access to the property, held on the agent. Read-only scope
Property
The numeric GA4 property id
Reached over
HTTPS from your network to the GA4 Data API. Nothing inbound
Schema
ga4 — so ga4.traffic_sources, ga4.page_views
Tables
9, of which four are on by default: traffic_overview, traffic_sources, page_views, events
Freshness
Batch tables run to yesterday, with the previous three days re-read each pass as GA4 finalises them
History
Back to 2020-10-01 on first sync
Live refresh
realtime_active_users only — a rolling 30-minute window with a 30-second freshness window
Local copy
An AES-256-GCM encrypted DuckDB file beside the agent, on your machine

The realtime table is capped at the top few hundred combinations Google returns in a snapshot, which is a limit of the realtime API rather than of this connector. For a complete picture of a day, use the batch tables.

In a cross-source query the middle part of a three-part reference is ga4. A connection called ga4_site reading traffic sources is written ga4_site.ga4.traffic_sources.

Vendor documentation: marketingplatform.google.com

FAQ

Questions about Google Analytics 4

Which tools can read Google Analytics 4 data through Query Streams?

All of them, from one connection: Excel, Google Sheets, MCP, REST API, Airtable, Baserow, SeaTable, Smartsheet, Anvil, Power BI, scheduled alerts and reports. Connect the account once and every surface reads the same read-only connection — there is no per-tool setup and no second copy of the data.

Do I have to open a firewall port to my Google Analytics 4 account?

No. The Query Streams Network Agent runs inside your network and opens a single outbound encrypted connection. Nothing listens for inbound traffic, no VPN is required, and the account keeps its existing firewall rules.

Can Query Streams change data in Google Analytics 4?

No. The agent enforces read-only at the point of execution — one statement at a time, SELECT and friends only. Credentials stay on the agent and are never sent to Query Streams.

What does Query Streams need to connect to Google Analytics 4?

A reachable host, a role and its password — the agent carries the driver, so nothing is installed on the account. Authentication: A Google service account key with read access to the property, held on the agent. Read-only scope. Property: The numeric GA4 property id. Reached over: HTTPS from your network to the GA4 Data API. Nothing inbound. Schema: ga4 — so ga4.traffic_sources, ga4.page_views.

Can I join Google Analytics 4 to another database in the same query?

Yes — that is a federated query. One statement can reference Google Analytics 4 and your other connections at once, written as connection.schema.table. Each source runs only the part it can and streams the result back; the join happens centrally, so the sources never connect to each other and nothing is copied or scheduled. Read-only applies to every piece — SELECT, WITH and EXPLAIN only — and there is a ceiling on how much any one source may hand over for a single query. Federated queries are a plan feature; the federated queries page carries the current source and size limits.

Put GA4 where the work happens

Install the agent, point it at your account, and pick a destination.

Read-only Outbound only Credentials stay on the agent