kimo
GuideIntermediate12 minMarketing

SEO reporting with Search Console and GA4, joined properly

Search Console and GA4 never match because they measure different events: Search Console counts clicks on Google’s results, GA4 counts sessions that start when your tag runs and consent allows it. Join them properly by aligning time zone, normalizing landing pages to canonical URLs, filtering GA4 to Google organic traffic, and comparing ratios and trends rather than raw totals. Then build one SEO dashboard that follows the funnel from impressions to revenue.

Sam Okafor · Growth lead
12 min read

At a glance

Level
Intermediate
Time
12 min

Prerequisites

  • Owner or full user access to the Search Console domain property
  • Viewer access or higher on the GA4 property
  • Optional: BigQuery project for the Search Console bulk export
  • A Kimo workspace with the Search Console and GA4 connectors

You will end up with

A weekly page-level model joining Search Console and GA4, a capture-ratio health check, and an SEO dashboard that runs from impressions to revenue with a weekly action list.

Why don’t Search Console and GA4 numbers match?

Because they count different things at different moments. Search Console records a click when someone clicks your result on Google Search. GA4 records a session when your page loads, the Google tag runs, and the visitor’s consent allows measurement. Between those two moments, visitors bounce before the tag fires, block scripts, decline cookies, or arrive on pages without the tag. Google’s documentation notes that tools such as Google Analytics only track users with JavaScript enabled, and that Search Console processes its data differently, for example by removing duplicates and bot visits1.

DimensionSearch ConsoleGA4What to do
What is countedClicks and impressions on Google resultsSessions and events on your siteCompare trends and ratios, not totals
Search enginesGoogle onlyOrganic Search includes all search enginesFilter GA4 to session source = google, medium = organic
Day boundariesPacific time (California)Property time zoneUse weekly or monthly grain, or shift dates
URL attributionCanonical URL of the resultActual landing page path, incl. parametersNormalize both to a canonical path
PrivacyAnonymized queries hidden from query rowsConsent and thresholds affect dataReport coverage alongside totals
Retention16 monthsConfigurable for explorations; standard reports aggregateStore Search Console history yourself
The main structural differences between the two tools.

The time zone difference alone explains many "the numbers changed overnight" questions: Search Console tracks daily data according to local time in California, while Google Analytics uses the site owner’s time zone, so daily figures will not align exactly1. Weekly aggregation removes most of this noise.

What exactly does each tool measure?

Search Console

In the Performance report, an impression is counted whenever your result appears in the current page of results, a click is counted when a user clicks through to an external page, and position is the topmost position of your link, averaged across queries. Crucially, click, impression and position data are attributed to the canonical URL of the link, and when you group by property, one search element containing several of your URLs counts as a single impression2. That is why property totals and page-level sums differ.

GA4

GA4 attributes sessions to channels using its default channel group. Traffic is Organic Search when the source matches a list of search sites or the medium is exactly organic3, which includes Bing, DuckDuckGo and others alongside Google. For a fair comparison with Search Console, filter to session source google and session medium organic.

The built-in GA4 Search Console reports

Linking the two products adds two GA4 reports. Google Organic Search Queries shows queries with Search Console metrics, and Google Organic Search Traffic shows landing pages with both Search Console and Analytics metrics. Search Console metrics are only compatible with Search Console dimensions plus landing page, device and country; data appears 48 hours after collection, and only 16 months are available4. These reports are useful for quick checks, but they do not support custom joins, longer history or revenue from your CRM. For that, you join the data yourself.

How big should the gap be?

There is no universal benchmark, and you should be wary of anyone who quotes one: the gap depends on your consent rate, page speed, audience and tag setup. What matters is that the ratio between GA4 Google-organic sessions and Search Console clicks is stable. Track it weekly. A sudden drop usually means a tracking problem (a template without the tag, a consent banner change, a redirect stripping the referrer), not an SEO problem.

Search Console clicks vs GA4 Google-organic sessions, weekly
  • Search Console clicks
  • GA4 Google-organic sessions
Figure. Illustrative data: simulated site where the ratio holds near 80% until a consent banner change in week 6 lowers recorded sessions while clicks keep growing.
Formula

Capture ratio=GA4 sessions (source = google, medium = organic) ÷ Search Console web clicks (same weeks, same pages)

where
Capture ratio
A health metric for your measurement, not for your SEO. Watch its stability, not its level.

How do you join Search Console and GA4 data?

Join at the landing-page level, by week, with country and device as optional dimensions. Queries cannot be joined to GA4, because GA4 does not receive the query; keep query analysis on the Search Console side and bring pages across.

Search Console and GA4 are required; BigQuery is optional for bulk export; a rank tracker and CRM add context and revenue.
  1. Step 1:

    Pull Search Console at page grain

    Use the API or the bulk data export, not UI exports. The UI exports at most 1,000 rows; the API and Looker Studio connector allow up to 50,000 rows per day per site per search type5.

  2. Step 2:

    Pull GA4 landing-page sessions for Google organic

    Filter session source to google and session medium to organic. Include engaged sessions, key events and, if available, revenue.

  3. Step 3:

    Normalize URLs on both sides

    Strip protocol, host, query string and fragment, lowercase, and remove trailing slashes, so both tools agree on the page key. Search Console already reports the canonical URL; GA4 reports what was loaded.

  4. Step 4:

    Aggregate to weeks

    Weekly grain absorbs the Pacific-time versus property-time difference and the 48-hour Search Console lag.

  5. Step 5:

    Join and keep both sides

    Use a full outer join so pages with clicks but no sessions (tag missing) and sessions but no clicks (non-indexable or Discover traffic) are both visible.

seo_pages_weekly.sql
sql
with gsc as (
    select
        date_trunc('week', date)                                        as week,
        rtrim(lower(regexp_replace(url, '^https?://[^/]+|[?#].*$', '', 'g')), '/') as page,
        sum(clicks)                                                      as clicks,
        sum(impressions)                                                 as impressions,
        sum(sum_position) / nullif(sum(impressions), 0) + 1              as avg_position
    from searchconsole.searchdata_url_impression
    where search_type = 'web'
    group by 1, 2
),
ga as (
    select
        date_trunc('week', date)                                         as week,
        rtrim(lower(regexp_replace(landing_page, '[?#].*$', '', 'g')), '/') as page,
        sum(sessions)                                                    as sessions,
        sum(engaged_sessions)                                            as engaged_sessions,
        sum(key_events)                                                  as key_events
    from ga4_landing_pages_daily
    where session_source = 'google' and session_medium = 'organic'
    group by 1, 2
)
select
    coalesce(gsc.week, ga.week)         as week,
    coalesce(nullif(gsc.page, ''), nullif(ga.page, ''), '/') as page,
    gsc.impressions,
    gsc.clicks,
    gsc.clicks::float / nullif(gsc.impressions, 0) as ctr,
    gsc.avg_position,
    ga.sessions,
    ga.engaged_sessions,
    ga.key_events,
    ga.sessions::float / nullif(gsc.clicks, 0)     as capture_ratio
from gsc
full outer join ga
    on gsc.week = ga.week and gsc.page = ga.page

Anonymized queries and row limits

Query-level reports never add up to the total. Google defines anonymized queries as those not issued by more than a few dozen users over a two-to-three month period; their text is hidden, but they are included in chart totals unless you filter by query5. The bulk data export to BigQuery includes all performance data for the property except anonymized query text6. For sites with long-tail traffic, the hidden share can be large.

Formula

Query coverage=Σ clicks on visible queries ÷ Total clicks (same property, same period)

where
Query coverage
Report it next to any query table so readers know what share of clicks the table explains

Practical consequences: analyze topics and pages rather than individual long-tail queries, use the bulk export to avoid sampling rows away, and store history in your own model because Search Console retains 16 months4. In Kimo, the Search Console connector keeps history from the day you connect; the setup doc explains property choices.

The SEO dashboard worth keeping

Most SEO dashboards are a wall of rankings. The one worth keeping follows the funnel from visibility to revenue, separates branded from non-branded demand, and surfaces pages that need action.

SectionMetricsQuestion
DemandImpressions, branded vs non-branded, by topicIs search demand for us growing?
CaptureClicks, CTR, average position by page groupAre we winning the clicks available?
ArrivalGoogle-organic sessions, capture ratioIs measurement healthy?
OutcomeKey events, pipeline or revenue from organic landing pagesDoes SEO produce business results?
Action listPages with high impressions and low CTR; pages losing clicksWhat should we fix this week?
Five sections, each answering one question.

Branded vs non-branded

Branded searches reflect awareness built elsewhere; non-branded searches reflect SEO reach. Search Console’s branded queries filter, rolled out from November 2025 for top-level properties with enough volume, splits Performance data into branded and non-branded using an AI-assisted classifier rather than regular expressions, and may occasionally misclassify queries7. Where it is not available, maintain your own brand-term list and apply it in the model.

AI Overviews and AI Mode

Google states that sites appearing in AI features are reported in the Performance report within the Web search type, with no separate breakdown, and that no special optimization is required to appear there8. Watch for pages where impressions rise while CTR falls: that pattern is consistent with answers being satisfied on the results page. Pair it with AI-search visibility tracking, described in the whitepaper One View of Marketing and our post on generative engine optimization.

From sessions to revenue

Join organic landing-page sessions to sign-ups and then to CRM opportunities or orders by the session or user identifiers your product records. The SEO funnel template ships this model, and our post on the SEO-to-signup funnel explains the attribution choices. In the app, the SEO page shows the result on simulated data.

How should you run a weekly SEO review?

A good SEO dashboard supports a 20-minute weekly review with a fixed agenda. Use complete weeks only (skip the last two to three days, which are still settling), compare with the previous four weeks and the same week last year, and end with a short list of actions with owners.

  1. Measurement health (2 minutes): is the capture ratio stable? Any pages with clicks but no sessions? If something broke, fix it before discussing performance.
  2. Demand (5 minutes): are non-branded impressions growing by topic? Is branded demand moving after campaigns or press coverage?
  3. Capture (5 minutes): which page groups gained or lost clicks, and was it position, CTR or demand? A click change with stable position and falling CTR points to a SERP change, not a ranking change.
  4. Outcomes (5 minutes): key events and pipeline from organic landing pages, with conversion rate per page group.
  5. Actions (3 minutes): pick up to five items from the action list below, assign owners, and log them next to the dashboard.

Monthly, add a content review: which new pages reached the top ten, which older pages are decaying, and which topics have demand but no page. Quarterly, revisit the brand-term list, page groups and targets. If SEO is one channel among several, roll its outcome numbers into the cross-channel overview described in our guide to setting up a unified marketing dashboard, so organic search is judged on the same revenue basis as paid media in Kimo Marketing.

Which pages need attention?

Combine position, CTR and trend to build a weekly action list. Four patterns cover most cases.

PatternSignalLikely action
Striking distanceAverage position 4–15, high impressionsImprove content depth, internal links, title relevance
Low CTR for positionCTR well below your own median at that positionRewrite title and description; check rich result eligibility
Decaying pageClicks down 30%+ over 8 weeks, position stableCheck SERP features and AI answers; refresh content
Tracking gapClicks steady, sessions near zeroCheck tag, redirects and consent banner on that template
Striking-distance pages, last 28 days
sql
select page, sum(impressions) as impressions, sum(clicks) as clicks,
       sum(clicks)::float / nullif(sum(impressions), 0) as ctr,
       avg(avg_position) as position
from seo_pages_weekly
where week >= current_date - interval '28 days'
group by page
having avg(avg_position) between 4 and 15 and sum(impressions) > 1000
order by impressions desc
limit 25

Troubleshooting

GA4 shows more Google-organic sessions than Search Console clicks

Check whether Discover or Google News traffic is being classified as organic in GA4; Search Console reports those under separate search types or reports. Also check for session restarts caused by UTM-tagged internal links or cross-domain issues.

Page totals do not add up to the property total

This is expected. By property, one search element with several of your URLs counts as one impression; by page, impressions are split per URL2.

Yesterday’s numbers changed

The newest Search Console data is preliminary and might change in the next few hours9, and GA4 shows Search Console data 48 hours after collection4. Exclude the last two to three days from week-over-week comparisons.

SEO reporting setup checklist

  • Search Console connected at the top-level (domain) property, with bulk export or API access.
  • GA4 filtered to source google, medium organic for comparisons.
  • URLs normalized identically on both sides; weekly grain used for joins.
  • Capture ratio tracked weekly with an alert on sudden drops.
  • Query coverage shown next to any query table.
  • Branded and non-branded demand split.
  • Organic sessions joined to key events and revenue.
  • History stored beyond Search Console’s 16 months.

Sources

10 references
  1. About Search Console data (opens in a new tab)
    Google Search Console Helpsupport.google.com

    Differences from Google Analytics; Pacific-time days; data processing.

  2. How are impressions, position, and clicks counted? (opens in a new tab)
    Google Search Console Helpsupport.google.com

    Canonical URL attribution; property vs page aggregation.

  3. [GA4] Default channel group (opens in a new tab)
    Google Analytics Helpsupport.google.com

    Organic Search covers listed search sites or medium = organic.

  4. Connect Search Console to Google Analytics (opens in a new tab)
    Google Analytics Helpsupport.google.com

    Two integrated reports, compatible dimensions, 48-hour lag, 16-month retention.

  5. A deep dive into Search Console performance data filtering and limits (opens in a new tab)
    Google Search Central Blog2022developers.google.com

    Definition of anonymized queries; 1,000-row UI export; 50,000 rows per day via API.

  6. Bulk data export of Search Console performance data (opens in a new tab)
    Google Search Console Helpsupport.google.com

    Daily export to BigQuery including all performance data except anonymized queries.

  7. Introducing the branded queries filter in Search Console (opens in a new tab)
    Google Search Central Blog2025developers.google.com

    AI-assisted branded classification; top-level properties; may misidentify some queries.

  8. AI features and your website (opens in a new tab)
    Google Search Centraldevelopers.google.com

    AI Overviews and AI Mode reported under the Web search type.

  9. Performance report (Search results) (opens in a new tab)
    Google Search Console Helpsupport.google.com

    Metric definitions; newest data is preliminary and may change.

  10. Table guidelines and reference (bulk data export) (opens in a new tab)
    Google Search Console Helpsupport.google.com

    searchdata_url_impression and searchdata_site_impression tables; zero-based sum_position and sum_top_position; average position = sum ÷ impressions + 1.

External sources were accessed at the time of writing. Kimo product details, customers and figures in examples are illustrative unless a source is cited.

0%

Mark as done

0 of 9 sections done

Frequently asked questions

Why are GA4 organic sessions lower than Search Console clicks?

Search Console counts clicks on Google results; GA4 only records a session when the page loads, the tag runs and consent allows it. Bounces before the tag fires, blocked scripts and declined consent all reduce GA4 counts.

Can I see Search Console queries in GA4?

Yes, through the linked Google Organic Search Queries report, but queries can only be combined with Search Console metrics and a few dimensions (landing page, device, country). GA4 events cannot be broken down by query.

Why don’t query rows add up to total clicks?

Anonymized queries, those not issued by more than a few dozen users over two to three months, are hidden from query rows but included in totals. Report query coverage next to query tables.

How long does Search Console keep data?

Sixteen months. Export it to your own storage, via the API, the BigQuery bulk export or a connector, to keep longer history.

Is AI Overviews traffic shown separately in Search Console?

No. Google reports AI Overviews and AI Mode traffic within the Web search type of the Performance report, without a separate breakdown.

Put it to work

Skip the setup — start from a working version.

SEO → signup funnel: Impressions to signups, by page and query, joined to your product database.

All resources
Template
Marketing

SEO → signup funnel

Impressions to signups, by page and query, joined to your product database.

Kimo team
4 min setup
ArticlePlaybooks
Marketing

GEO: how to show up in AI answers — and measure it

Generative engine optimization explained with the research behind it, what Google says, and what you can and cannot measure today.

Sam Okafor
12 min read

Every channel. One dashboard.

Social, SEO, paid, email, PR and AI-search visibility, normalized into one command center your whole team reads the same way.