Skip to main content
Methodology · Author Engagement Time

Why GA4 says your authors get 40 seconds — and how we get to the real number

GA4 has three different scopes for data — event, session, and user. Mix them wrong and your best author looks like your worst. Here is exactly how we navigate that limitation to show real per-author engagement time.

Naive query
0s

userEngagementDuration / sessions grouped by customEvent:post_author. Returns ~one article's read time. Looks broken.

Glarify's approach
0m 0s

Landing-page attribution: when a session starts on an author's article, we credit the entire session's engagement to them.

Foundation

GA4 has three scopes. Mixing them is where it all goes wrong.

Every dimension and metric in GA4 lives in exactly one scope. If you join something event-scoped (like a custom event parameter) with something session-scoped (like total session count), the math is silently misleading.

Session scope

session_source, session_medium, landing_page, session_campaign — set when the session begins, then attached to every later event.

Strength

Perfect for "this whole visit started on X" or "came from Y".

Limitation

Cannot change mid-session, even if the user navigates somewhere different.

Author angle

If post_author were truly session-scoped, naive division would work. But GA4 only treats it that way for the LANDING page — not for every author the visitor reads.

The Trap

One session. Three authors. GA4 splits the time.

Watch what happens when a single visitor reads articles by three different authors in one visit. Press play and see how the naive query buries the author who actually earned the click.

Step 0 / 4
A

Lands on Author A

Author A's post

95s
B

Clicks related: Author B

Author B's post

50s
A

Back to Author A

Author A's post

30s
C

Skims Author C

Author C's post

12s
Total session engagement0s

Naive: post_author × engagement

SELECT customEvent:post_author, SUM(userEngagementDuration) / sessions
Author A
Author B
Author C

Each author only gets credit for the seconds spent on their own page. Author A — who earned the click — looks no better than Author B. Author C, who got 12 lazy seconds, gets the same per-event treatment.

Glarify: landing-session attribution

landingPagePlusQueryString → post_author map → SUM(engagement) / sessions
Author A
landing
Author B
Author C

Author A landed the visitor and gets credit for the entire stickiness of the session — including the time the visitor spent on B and C. That is the question content teams actually ask: "who pulls people in?"

The Pipeline

How we actually compute it

Five steps, one batched call per property, deterministic joins. No fuzzy matching, no machine guessing — just careful schema design around GA4's scope rules.

  1. Step 1

    Query 1 — Landing-page engagement

    For each property, ask GA4: per landing page, total sessions and total userEngagementDuration. This is the only metric in GA4 that legitimately spans a whole session, anchored to where it began.

    dimensions: [landingPagePlusQueryString]
    metrics:    [sessions, userEngagementDuration]
  2. Step 2

    Query 2 — Path → author map

    Separately, fetch pagePath × customEvent:post_author × screenPageViews. For every URL we know who wrote it (using the highest-view author when reassignments happen).

    dimensions: [pagePath, customEvent:post_author]
    metrics:    [screenPageViews]
  3. Step 3

    Normalize both sides

    GA4 returns landing paths with query strings, AMP variants, pagination and casing differences. Our normalizer (src/lib/author-attribution.ts) collapses all of that to one canonical key on both sides so the join actually matches.

    /Author/Bio?utm=x  →  /author/bio
    /post/amp/        →  /post
    /page/2/          →  /
  4. Step 4

    Join + aggregate

    Join landing rows to the author of that path. Sum sessions and engagement per author across all properties. The final number is total engaged seconds ÷ landing sessions for that author.

    avgTime[author] = Σ engagementDuration / Σ sessions
                   (over landings owned by author)
  5. Step 5

    Background fetch + merge

    Landing attribution is heavier than a vanilla GA4 call, so we run it in the background after the page paints. Per-page reading time shows immediately; landing-session time slots in once ready, no opt-in required.

Try it yourself

See the gap with your own assumptions

Drag the sliders to model an author. The naive number is what GA4 hands you by default. The Glarify number is what landing attribution surfaces.

420
2.4
55s

GA4 default (post_author scope)

55s

Just one article's read time.

Glarify (landing-session)

2m 12s

Whole visit credited to the author who earned the landing.

Improvement factor2.4×
Engaged minutes / mo924
Solid — meaningful engagement
Honest limitations

The four things this still cannot do

Landing attribution is a much better answer than the naive query — but it is not magic. Here is exactly where it bends.

Untagged pages drop out

If post_author was added to your site after some posts were live, those older pages have no author parameter. Their landing sessions don't get credited to anyone. We surface this as a coverage badge so you know what fraction of traffic is attributable.

GA4 thresholding on small audiences

When an author has fewer than ~50 sessions in the date range, GA4's privacy thresholding can return zero or aggregate the row away. We mark those rows as "low data" rather than implying zero engagement.

Reassigned posts

If an article changes author over time, GA4 will return rows for both. We pick the author with the most pageviews in the date range to own the path. Aliases (configured in admin) take precedence so admins can merge variants.

Single-page sessions

GA4 sometimes records zero engagement for sessions that fired only one event before the user left. Those still count toward the session denominator, which can pull the average down. This is GA4's definition, not a bug — we report what GA4 reports.

See it in your data

Stop wondering if your authors are bad. They probably aren't.

Connect a GA4 property and Glarify will run the landing-attribution pipeline across every author in your library. Most teams discover their best writers were hiding behind GA4's defaults.