In short
- GA4 can take 24–48 hours to finish a day, and late events can still arrive after that.
- A period ending today compared with a complete one shows a decline that is not real.
- End GA4 comparisons two days ago, Search Console three.
- Google Ads spend settles within hours; its conversions keep arriving for longer.
You check yesterday's figures in Google Analytics 4 in the morning: 410 sessions, two sales. You check again in the afternoon and it says 460 sessions and three sales. Tomorrow it may say something else again. Nothing is wrong with your tracking. GA4 is still counting.
Knowing how long that takes matters less for yesterday itself than for every comparison that includes it. A week that ends today, set against a full week before it, will nearly always look like a decline — and the decline is not real.
Why the recent days are not final
GA4 does not count your visits as they happen. Events arrive, are queued, and are processed into the reports in batches, and Google says that processing can take 24 to 48 hours. Until it is done, the most recent days show part of what happened.
- Today is always incomplete. The day is not over, and what has happened so far is not all processed yet.
- Yesterday is usually close, but can still move, sometimes noticeably.
- The day before is normally settled.
Some data arrives late on top of that. A mobile app that was offline sends its events when it reconnects, and GA4 accepts events that reach it up to 72 hours late, filing them on the day they happened. So a day can still change slightly after it looks finished.
The Realtime report is the exception: it shows the last 30 minutes as they arrive. It is good for checking that a new tag fires, and not for counting a day.
The false decline this causes
Compare “the last 7 days including today” with the 7 days before, and you are comparing about six days of data with seven. On a business that did not change at all, that reads as a drop of up to one seventh — around 14% — before anything real has happened.
The same thing happens in any report that compares a period ending now with a complete one: a month to date against last month, a dashboard tile showing “this week”, a weekly email sent on Monday morning about a week that ended a few hours earlier. It is easy to spot when you know to look for it, and easy to act on when you don't — pausing a campaign over a drop that was only GA4 catching up.
Search Console and Google Ads run on their own clocks
- Search Console is slower. Its Performance report usually shows data from two or three days ago at the latest, and the most recent day it shows can still be partial.
- Google Ads is quicker for clicks, impressions and spend, which are close to final within hours. Its conversions keep changing for longer, because it files a conversion on the day of the ad click: a sale today for a click last week raises last week's figure. (More on that in why Google Ads and GA4 never agree on conversions.)
- The BigQuery export of GA4 arrives as a daily table, usually the following day, and Google can update it afterwards to add events that arrived late.
So when you put spend from Google Ads beside revenue from GA4, the last day or two can show money spent and revenue not yet counted. That is not a bad day for your ads, only a day GA4 has not finished.
How to compare fairly
- End your periods two days ago for GA4, and three for Search Console. “The 7 days ending the day before yesterday” against the 7 days before that is a fair comparison.
- Compare whole weeks with whole weeks. Most sites have a weekly rhythm, so seven days against seven days, both settled, removes the weekday effect as well.
- Treat today as a running count, not a result. It is useful for “is anything happening?”, and not for “are we up or down?”.
- Read the last two days of a chart as unfinished. A line that dips at the right-hand edge almost always does.
How Glancely handles it
Glancely's date ranges end at the last day each source has finished counting: two days ago for GA4, three for Search Console, and yesterday for the Google Ads page, whose spend and clicks are final within hours. Pages that put Ads beside GA4, like Revenue, use GA4's window, so spend is never weighed against revenue still being processed. This month so far also stops at the last finished day once the month has one. A range includes unfinished days only when you ask for them — Today, Yesterday, a custom range ending today, or a month that is a day or two old — and then the page says so, naming how many days are still being counted. A single day is compared with the same weekday a week earlier, not with the day before, so a Monday is never measured against a Sunday.
Kosmas Botsis · Founder of Glancely
Kosmas Botsis is the founder and lead data engineer of KB Analytics, an analytics engineering practice in Athens working with clients across Europe and the US: more than 250 projects for over 194 clients, and in Toptal's top 3% of talent. Glancely is what came out of that work.
About Kosmas at KB AnalyticsMore from the blog
- Why your return on ad spend counts sales your ads didn't make
Divide all of your revenue by your ad spend and the ads take credit for every organic, direct and email sale. Here is how to work out the return on the channels you actually pay for, and why it can be five times lower.
- Why your Google Ads campaigns don't line up with GA4's
Put Google Ads spend beside GA4 revenue by campaign and half the rows often come back empty, because the join is on a name and the names don't agree. Here is where GA4's campaign name comes from, and how to match them without hiding your best campaign.
- Where Performance Max shows up in GA4
GA4 files Performance Max visits under a channel called Cross-network, not Paid Search or Paid Shopping. Put its spend anywhere else and every channel's return is wrong; here is where it belongs and how to read it.