Pricing

GA4 in Google Sheets: How to Get Hourly Refresh (Not Just Daily)

Sessions48,291+14.2%Bounce Rate38.4%−3.1ppAvg Duration2m 41s+0:08Conversions1,284+22.7%Sessions over 30 days
JW
James Whitfield

The official GA4 add-on only refreshes once a day. Learn three methods to get hourly, or even 15-minute, GA4 data in Google Sheets without breaking your API quota.

The official Google Analytics add-on for Google Sheets caps you at one scheduled refresh per day. If you are running a paid campaign that goes live at noon and want to catch a broken UTM parameter before it burns through your budget, daily is not good enough.

This guide covers every viable method to get GA4 data into Google Sheets on an hourly schedule, including the tradeoffs, the API quota math, and which approach fits which team size.

Why the Default Add-On Falls Short

The Google Analytics add-on (available from the Google Workspace Marketplace) was built for end-of-day reporting. Its scheduler lets you pick a time of day: once. There is no option for "every hour" or "every 15 minutes." For teams managing always-on paid media, product launches, or promotional events, that gap between data and reality is costly.

The underlying issue is not technical. The GA4 Data API supports high-frequency calls. The add-on simply never exposed sub-daily scheduling in its UI.

What you actually lose with daily-only refresh

Consider these common scenarios where a 24-hour data gap has real dollar consequences:

  • Paid media campaigns: You launch a Google Ads campaign at 10 AM. By noon, a UTM parameter misconfiguration is sending all traffic to the wrong landing page. With daily refresh, you will not see it until tomorrow morning, 14 hours of wasted spend.
  • Promotional events: You run a flash sale from 2 PM to 6 PM. Daily refresh shows you aggregate sales for the full day, but you cannot see the hourly shape of the campaign: when the spike started, when it dropped off, whether a push notification drove a second peak.
  • A/B test monitoring: You are testing two landing pages. Conversion rates in GA4 update in the processed API with a lag. A daily report might show you data that is up to 36 hours old at the time you read it, meaning a clearly losing variant runs far longer than necessary.

These are not edge cases. They are standard campaign management situations where data latency creates direct business cost.

Method 1: Apps Script with an Hourly Time Trigger

Apps Script is Google's built-in automation layer for Sheets, and it has direct access to both the GA4 Data API and the Sheets API. You can build an hourly refresh yourself without installing anything.

What you need

  • A Google Cloud project with the Google Analytics Data API enabled
  • A service account with Viewer access to your GA4 property
  • The service account's JSON key stored in Apps Script's PropertiesService

How it works

  1. Write a function in Apps Script that calls analyticsdata.googleapis.com/v1beta/properties/{propertyId}:runReport with your desired dimensions and metrics.
  2. Parse the response and write it to a named sheet tab.
  3. Set a time-based trigger: Edit > Current project's triggers > Add trigger, choose your function, and set the time interval to "Every hour."

Sample trigger setup (no API keys in code)

javascript
function createHourlyTrigger() {
  ScriptApp.newTrigger('fetchGA4Data')
    .timeBased()
    .everyHours(1)
    .create();
}

The fetchGA4Data function reads credentials from PropertiesService, builds the API request body, fetches the report, and writes rows to the sheet.

Full Apps Script request structure

The GA4 Data API request body follows this structure when called from UrlFetchApp:

javascript
var requestBody = {
  dateRanges: [{ startDate: "today", endDate: "today" }],
  dimensions: [
    { name: "sessionCampaignName" },
    { name: "sessionMedium" }
  ],
  metrics: [
    { name: "sessions" },
    { name: "conversions" },
    { name: "totalRevenue" }
  ],
  limit: 1000
};

The response is a JSON object with dimensionHeaders, metricHeaders, and rows. Each row is an array of dimensionValues and metricValues you iterate over to write to the sheet.

Limitations

  • Each run counts against your quota (see the quota section below).
  • The setup takes 2–4 hours for someone comfortable with JavaScript; more for others.
  • You are responsible for error handling, token refresh, and maintaining the script when the API changes.
  • Apps Script execution time is capped at 6 minutes per run. If your report query takes longer than that (uncommon but possible for large properties with many dimensions), the trigger will time out and no data will be written.

Method 2: Third-Party Connectors with Sub-Daily Scheduling

Several connectors sit between GA4 and Sheets and handle the API authentication, scheduling, and data writing for you. The key differentiator is how granular their refresh schedules go.

Supermetrics

Supermetrics added hourly refresh as a feature on its higher-tier plans. You configure a data source, define your dimensions and metrics in the Supermetrics sidebar, and set the schedule to hourly. The connector manages OAuth and quota internally.

Minimum plan for hourly: Supermetrics for Google Sheets Pro or higher.

brooked.io

brooked.io supports 15-minute refresh intervals, which is the highest frequency available among managed connectors as of mid-2025. It connects directly to GA4's Data API, writes results to a sheet tab you designate, and handles token refresh automatically. The 15-minute option is available on all paid plans.

Why this matters for campaigns: A 15-minute window lets you catch a tracking issue or a sudden CPC spike within one reporting cycle rather than waiting until the next morning.

Coupler.io

Coupler supports hourly scheduling for GA4. The setup is no-code. You select GA4 as a source, Google Sheets as a destination, pick your metrics, and choose hourly from a dropdown. Coupler also handles historical backfill if you need to seed a new sheet.

Method 3: GA4 to BigQuery to Sheets

For teams that need near-real-time data and are comfortable with SQL, the GA4 → BigQuery export pipeline is the most powerful option: though also the most complex to set up.

How the pipeline works

  1. Enable BigQuery export in GA4 Admin. Go to Admin > Product links > BigQuery links. Enable daily and/or streaming export. Streaming export pushes events to BigQuery within minutes (latency varies; typically under an hour).
  2. Query BigQuery from Sheets using Connected Sheets. In Google Sheets, go to Data > Data connectors > Connect to BigQuery. Write a SQL query that aggregates the GA4 event data you need.
  3. Schedule the Connected Sheets query. Connected Sheets has its own refresh scheduler. You can set it to refresh hourly, or use an Apps Script trigger to call SpreadsheetApp.getActiveSpreadsheet().getDataSources()[0].refreshAllLinkedDataSources() on a time trigger.

When to use this

  • You need item-level or event-parameter-level data not available in the standard Data API.
  • You already have a BigQuery environment for other data sources.
  • Your analytics team is SQL-literate.

When not to use this

  • You just need session, user, and conversion metrics at the date or campaign level.
  • Your team does not have a Google Cloud project set up.
  • You want something running within an hour rather than a day.

BigQuery streaming vs. daily export for hourly use cases

The GA4 BigQuery export has two modes. The daily export writes all previous-day events once per day to a permanent events_YYYYMMDD table. This has zero value for hourly monitoring. The streaming export writes events to events_intraday_YYYYMMDD within minutes of collection, which enables near-real-time queries. Streaming export incurs higher BigQuery costs than standard storage but is the only path to near-real-time data. The intraday table is overwritten at the end of the day by the final daily table, so you always have clean partitioned history.

Connector Comparison Table

MethodMinimum RefreshSetup TimeCostSQL RequiredBest For
Official GA4 Add-OnDaily5 minFreeNoEnd-of-day reports
Apps Script + triggerHourly (configurable)2–4 hoursFree (dev time)No (JS)Teams with a developer
SupermetricsHourly (Pro plan)30 minPaidNoEnterprise marketing teams
brooked.io15 minutes10 minPaidNoActive campaign monitoring
Coupler.ioHourly20 minPaid (free tier limited)NoMid-size teams, no-code
GA4 → BigQuery → SheetsNear real-time (streaming)1–2 daysGCP costs + dev timeYesAnalytics teams, event-level data

API Quota Considerations

The GA4 Data API has a default quota of 10,000 requests per property per day. This sounds large, but hourly refreshes compound quickly.

  • One report, hourly: 24 requests per day. Quota is not a concern.
  • Five reports, hourly: 120 requests per day. Still fine.
  • Twenty reports, every 15 minutes: 1,920 requests per day. Approaching 20% of quota.
  • Fifty reports, every 15 minutes: 4,800 requests per day. Half your quota consumed.

Quota tips

  • Consolidate multiple small reports into one API call using multiple dimension/metric combinations where possible.
  • Cache results in Sheets rather than re-fetching data that hasn't changed (e.g., yesterday's data will not change, so only refresh today's rows).
  • Request a quota increase through Google Cloud Console if you have a legitimate high-volume use case.
  • Third-party connectors like brooked.io pool quota management across their infrastructure. You benefit from their optimization without managing it yourself.

Troubleshooting

The Apps Script trigger runs but the sheet does not update. Check the execution log (Extensions > Apps Script > Executions). The most common causes are an expired service account key or a changed GA4 property ID. Verify both in PropertiesService and re-save.

Supermetrics shows "Quota exceeded" errors. Supermetrics uses a shared API key model on some plans. Spread your refresh times across the hour rather than scheduling all reports at :00. Contact support to request dedicated quota allocation.

brooked.io is writing data but timestamps look wrong. Check the timezone setting in your brooked.io connector configuration. GA4 reports data in the property's reporting timezone; if your sheet uses a different timezone, the hour boundaries will appear shifted.

BigQuery streaming data is not appearing in Sheets. Streaming inserts can take up to 90 minutes to be available in standard queries. Use the _PARTITIONTIME pseudo-column with a slight lag buffer in your SQL, or wait for the daily table partition if freshness is not critical.

The GA4 add-on scheduled report stopped running. Google's add-on scheduler sometimes silently fails when the spreadsheet owner's Google session token expires. Open the add-on, re-authenticate, and re-save the schedule.

Bottom Line

The official GA4 add-on is adequate for static dashboards and end-of-day reporting. For active campaign management where a 24-hour lag means wasted spend or missed opportunities, you need one of three approaches: Apps Script for a free-but-manual solution, a third-party connector like brooked.io for a managed 15-minute refresh, or the BigQuery pipeline for event-level granularity.

Most marketing teams running paid media will get the best return on investment from a managed connector. The setup takes under 30 minutes, there is no code to maintain, and the quota management is handled automatically.

Get Hourly GA4 Data in Sheets Today

brooked.io connects to GA4 and refreshes your Google Sheets every 15 minutes, no code, no quota headaches. Start your free trial at brooked.io and have live campaign data in your sheet before your next meeting.

Related guides on brooked.io:

Troubleshooting quick reference

Frequently asked questions

Can I get real-time GA4 data in Google Sheets?

Not through the standard Data API. The API returns processed data, which typically has a 24–48 hour lag for some metrics and a shorter lag (minutes to a few hours) for others. For true event-stream data with minimal latency, the GA4 → BigQuery streaming export is the closest option.

Does hourly refreshing violate GA4's terms of service?

No. The GA4 Data API is designed for programmatic access. As long as you stay within your quota limits and use OAuth or service account credentials properly, hourly or sub-hourly refreshes are fully within the terms.

Will my sheet get rate-limited if I run multiple hourly reports?

Quota is measured at the property level, not the sheet level. If you have ten sheets all pulling from the same GA4 property hourly, each one consumes quota from the same 10,000-request-per-day pool.

Can I schedule different reports at different frequencies in the same sheet?

With Apps Script, yes. You create separate time triggers for separate functions. With most third-party connectors, each data block or query has its own independent refresh schedule.

What is the cheapest way to get hourly GA4 data in Sheets?

Apps Script is free. The only cost is the time to build and maintain it. If your team has a developer available and the volume of reports is small, Apps Script is the most cost-effective path.

Ready to connect your data to Google Sheets?

Brooked's free tier covers 100 imports per month with AI Analyst included, no credit card required.

Install Brooked free →

Also in Analytics & BI

More Analytics & BI guides

Analytics & BI

How to Connect GA4 to Google Sheets

The free official Google add-on (GA4 Reports Builder) with the scheduling step nobody documents, the native Connected Sheets GA4 connector, BigQuery export for unsampled event-level data, plus the sampling and '(other)' aggregation traps that make GA4 numbers in your sheet diverge from the UI.

JW
James Whitfield
Read
Analytics & BI

How to Connect Looker to Google Sheets

All 4 ways to get Looker data into Google Sheets: Connected Sheets, scheduled delivery, API, or a no-code add-on.

JW
James Whitfield
Read

Get your spreadsheet hours back

Brooked sets up in seconds. Your team is querying live data before lunch.

Get started free