Connect Google Analytics 4 to Google Sheets
Run GA4 reports over any dimensions and metrics — sessions, users, conversions, channels — and land them in a sheet on a schedule. Presets get you started; every field stays editable.
Coming soon — join the list to get early access
What you can pull from Google Analytics 4
Google Analytics 4 exposes 5 objects you can pull, each as its own job. Every run will pull the records into a flat table, so nested fields arrive as ordinary columns that Google Sheets can sort, filter and total without further work.
Traffic overview
Daily sessions, users and page views.
| Column | Type | Notes |
|---|---|---|
| date | dimension | — |
| sessions | metric | — |
| activeUsers | metric | — |
| screenPageViews | metric | — |
Traffic acquisition
Daily traffic split by default channel group.
| Column | Type | Notes |
|---|---|---|
| date | dimension | — |
| sessionDefaultChannelGroup | dimension | — |
| sessions | metric | — |
| activeUsers | metric | — |
| engagedSessions | metric | — |
Top pages
Most-viewed pages with engagement.
| Column | Type | Notes |
|---|---|---|
| pagePath | dimension | — |
| screenPageViews | metric | — |
| activeUsers | metric | — |
| userEngagementDuration | metric | Seconds |
Conversions / key events
Event counts by day and event name.
| Column | Type | Notes |
|---|---|---|
| date | dimension | — |
| eventName | dimension | — |
| eventCount | metric | — |
| activeUsers | metric | — |
Geography
Users and sessions by country.
| Column | Type | Notes |
|---|---|---|
| country | dimension | — |
| activeUsers | metric | — |
| sessions | metric | — |
Options you can set
- property_id
- The numeric GA4 property ID, not the G-XXXXXXX measurement ID
- dimensions
- Prefilled by the preset, and editable
- metrics
- Prefilled by the preset, and editable
- date_range
- yesterday, last_7_days, last_28_days, last_90_days or custom
- keep_empty_rows
- Include rows whose metrics are all zero — defaults to
false
How it lands in Google Sheets
Google Sheets accepts append and overwrite writes. Overwrite replaces the target range, which suits a snapshot; append adds rows underneath, which suits a log you are accumulating. There is no upsert here, so rows are added or replaced rather than merged.
- Append adds rows below existing content; overwrite replaces the target range.
- No upsert: a spreadsheet has no primary key, so there is nothing to merge on. Use Airtable or Postgres if rows must be updated in place.
- Google caps a spreadsheet at 10 million cells across all tabs. Filter before writing rather than after.
Authentication
You connect Google Analytics 4 once through OAuth and the credential is stored server-side, never pasted into a cell or a formula. Only the scopes the connector actually calls are requested — the table below lists each one and what it is for.
What Google Analytics 4 is asked for
- analytics.readonly sensitive
- Run GA4 reports. Read-only
- userinfo.email non-sensitive
- Label the connection
Keeping runs incremental
Yes. Each run pulls a rolling date window rather than the whole history, so nothing has to persist a cursor between runs.
Because Google Sheets has no upsert, decide what a re-run should mean before you schedule it. Overwrite keeps a current snapshot; append accumulates history and will grow without bound.
Limits and pacing
These are the provider-side ceilings that shape a schedule, not ours. Knowing them up front is the difference between a job that runs quietly every morning and one that starts failing the week your data grows.
| Limit | Value | Applies to |
|---|---|---|
| Date window Narrowed each run rather than cursored, so there is no state to corrupt. | per-run preset | Google Analytics 4 |
Common gotchas
Most of what goes wrong with a scheduled sync is not a bug — it is a detail of how one side behaves that nobody wrote down. These are the ones that come up for this pair.
Presets are a starting point, not a cage
Each preset prefills dimensions and metrics that are known to work together; both remain editable.
Not every dimension pairs with every metric
GA4 rejects invalid combinations at query time rather than warning you when you pick them. If a custom pairing 400s, that is why - start from the closest preset and change one thing at a time.
Zero rows are dropped by default
keep_empty_rows is false, so days with no activity simply do not appear. If you are charting a continuous series, that gap is a missing row rather than a zero.
An open-ended range beats a padded one
Writing to A2:D is better than A2:D1000 for appends: the padded form reserves rows you may not need and makes the append boundary ambiguous.
Set it up in four steps
- 1
Connect Google Analytics 4
Connect your Google account, then choose a GA4 property.
- 2
Connect Google Sheets
Connect your Google account once. Paste a spreadsheet URL or ID.
- 3
Shape the data
Select the columns you want, filter rows, cast types and add computed fields. Everything else is dropped before it reaches the destination.
- 4
Schedule it
Run once, or on a cron. Every run refreshes Google Sheets with the latest Google Analytics 4 data.
Do I need an add-on or extension for this?
No. The job runs server-side and writes into Google Sheets through its API, so there is nothing installed in the spreadsheet itself. It keeps running when nobody has the file open, and a copy of the file does not need anything installed to work.
How often does the data refresh?
On whatever schedule you set with a cron expression — hourly, daily, or a specific time on specific days. Each run pulls the latest from Google Analytics 4.
Do I need to write any code?
No. You connect both sides, map the fields in a wizard and set a schedule. Computed fields accept small expressions — abs, round, min, max, len — but there is nothing to host or maintain.
Which property ID do I use?
The numeric one from Admin → Property details, not the G-XXXXXXX measurement ID. They are different identifiers and the Data API only accepts the numeric form.
Can I choose my own dimensions and metrics?
Yes. The presets prefill combinations known to work together, which saves the round of trial and error GA4 otherwise demands, but both lists stay editable.
Do I have to give access to my whole Google Drive?
No. Only the spreadsheets scope is requested. The Drive scope that most spreadsheet tools ask for is a restricted scope granting read access to every file you own; it is deliberately not requested here, which is why you paste a spreadsheet URL rather than browsing Drive.
Will this keep working if I copy the sheet?
The job writes to a specific spreadsheet ID, so a copy will not receive data until you point a job at it. Nothing is installed in the file itself, though, so copying never breaks the original.
When will Google Analytics 4 be available?
Google Analytics 4 is built and waiting on verification. Join the early-access list and we will let you know the moment it opens.
Other sources into Google Sheets
Related reading
Export Stripe data to Google Sheets
Stripe's dashboard exports are manual and stale the moment you download them. Here is how to keep customers, invoices and charges fresh in a sheet instead.
Import a CSV from a URL into Airtable
Point a job at a CSV link and it re-reads it on your schedule — no download, no manual import. Here is the setup, and the field-type trap to avoid first.
Get data into Google Sheets without an add-on
Every major Sheets data tool is an add-on you install, authorise and keep updated inside the spreadsheet. Here is how to schedule the same imports without one.