Writing / Measurement & reporting
Why your dashboard and GA4 show different numbers
Your dashboard and the report inside Google Analytics 4 show different totals for the same period. Here is how to investigate the difference before choosing which number to use.

Suppose your monthly dashboard in Looker Studio shows a different session total from the report you open inside Google Analytics 4 (GA4). You have selected the same website property and calendar month in both. Which number should go into the report you send to your team?
That is the problem this guide addresses: a dashboard or automated report outside GA4 disagrees with a report inside GA4, even though both use GA4 data. Looker Studio is the example here. The same investigation can help with a spreadsheet or custom report that retrieves data through the Google Analytics Data API, the service software uses to request GA4 report data.
First establish whether the two reports are asking for the same thing. Then check what happened when the data was retrieved, calculated and refreshed. The aim is to explain the difference and decide whether to correct the dashboard, wait for an update, or use one result with a clear explanation.
Google documents differences between Data API results and reports viewed inside GA4. Query settings, aggregation and processing conditions can all matter. The useful outcome of an investigation is an explanation you can reproduce, with a clear decision about which result is suitable for the report.[1]
Write down the two report definitions
Start with the smallest result that disagrees: one metric, one period and as little breakdown as the question allows. Keep a copy of both outputs before changing anything. Record when each was retrieved so a later refresh does not quietly replace your evidence.
Identify the exact report on each side. For the Looker Studio example, record the chart and its data source, then name the GA4 report you are checking it against. A standard report and an exploration inside GA4 can also apply different settings. A BigQuery export introduces another set of considerations; it is outside the scope of this guide.
- The measure
- Record the exact metric and dimensions, including their API names when available. “Users” is too vague for reconciliation: active users and total users have different definitions.[2]
- The reporting scope
- Match the property, explicit start and end dates, property time zone and any relevant currency. API date ranges include both endpoints. Relative dates such as “yesterday” resolve using the property's reporting time zone, so save the actual dates used.[3]
- The selection
- Capture filters, table searches, comparisons and segments, including their operators. A search for a page path is not automatically equivalent to a filter on page path and query string.
Be particularly careful when using an exploration as the reference. The table Search field in a standard report uses case-insensitive contains matching. Exploration filters offer match types and are case-sensitive. This distinction concerns table Search, not every filter in GA4. Google also explains that some fields or comparisons cannot transfer directly between reports and explorations. Recreating the screen's appearance does not establish an equivalent query.[4]
Check what happens between retrieval and display
Ask for the result before the dashboard's calculations, joins and presentation rules. If the retrieved data agrees with your reference but the displayed result does not, you have narrowed the investigation to the steps between them. Look at calculated fields, grouping, joins, filters and any totals assembled in a spreadsheet.
A common trap is treating a count of distinct people as something that can always be added. The same person can appear on several days or in several categories. Adding those separate user counts can count that person more than once. Request the total for the intended scope rather than assuming a sum of daily or category-level counts gives the same answer.
The dimensions matter too. First user source and Session source describe different acquisition contexts. Choose the dimension that answers the report's question, then compare like with like. Changing attribution settings to force agreement would change the measurement rather than explain it.[5]
If the automated report retrieves multiple pages of API results, check that it has retrieved the complete query result. The API's rowCount describes the result's total row count independently of the response's limit and offset. Compare it with the distinct result rows retrieved across pages while holding the query constant. A connector's own row count may describe a transformed table instead, so establish what it counts first.[6]
This checks extraction completeness for that query. It does not prove that every collected event is represented, and increasing the page size cannot recover detail already grouped into an (other) row.[1]
Read the evidence behind the number
When you can access the API response, keep its metadata alongside the values. Metadata is information about how the report was produced. Several fields can help you decide what to investigate, but they do not identify the cause of a mismatch on their own.[7]
Was the result sampled?
samplingMetadatas describes sampling for each requested date range when it applies. The field is absent for unsampled results. Record what the response actually says; a large dataset alone is not proof that this particular report was sampled.
Could a threshold affect the result?
subjectToThresholding indicates that the report is subject to thresholds. A true value does not prove rows were withheld: all the data may meet those thresholds. Keep that distinction in the explanation you give a stakeholder.
Was detail grouped into “other”?
dataLossFromOtherRow describes grouping in the underlying aggregate data. It can remain true even when a filter removes the visible (other) row. The absence of that row on screen therefore does not settle the question.
Is another restriction recorded?
Inspect any schema restrictions, truncation reasons or empty-report explanation returned with the response. Preserve the explanation rather than translating every missing result into zero. Currency and time-zone metadata also help confirm the reporting context.
If your connector does not expose the request or metadata, record it as unavailable and ask the report owner or supplier for it. You can still compare visible settings and timestamps. You cannot conclude that there was no sampling or restriction simply because the connector shows no warning.
Google's documentation says the API and interface use the property's reporting identity. Do not assume the API always uses a different identity. A setting change between retrievals can affect the comparison, which is another reason to retain when and how each result was obtained.[1]
Repeat a controlled comparison
Recent reports can change while data is processed. Google describes different freshness intervals and warns that processing can take 24 to 48 hours. Some attribution updates can take longer. Waiting exactly two days is therefore not a guarantee that all numbers will match or remain unchanged.[8]
Use a completed period for the initial diagnosis and record the time of each retrieval. Where a dashboard caches or extracts data, establish when its underlying data was refreshed, not just when someone opened the page.
Then change one relevant condition at a time. If you discover different date ranges, correct that difference and rerun the comparison before changing a filter. Keep the previous result and note what changed. If the gap disappears, you have evidence about that change. If several settings changed together, you cannot tell which one explained it.
For a period total that differs from a table, compare the metric with and without the breakdown. For an incomplete extraction, verify the retrieval of all result pages. For a possible processing delay, repeat the same query later. These tests answer different questions; collecting more screenshots of the unchanged mismatch will not resolve them.
Decide what the evidence permits
Correct a demonstrated mismatch
If a wrong filter, missing result page or transformation explains the difference, fix that step and rerun the original comparison. Preserve the evidence that the repair addressed the identified problem.
Recheck a changing result
If processing or an extraction refresh remains a plausible cause, set a specific time to repeat the same comparison. Label the current result as provisional where it matters to the decision.
Explain a documented difference
When the reports legitimately measure different things, choose the one suited to the business question and explain the boundary. Do not quietly change a definition just to make totals agree.
Escalate an unresolved discrepancy
Provide the smallest reproducible comparison: report definitions, retrieval times, observed difference, available metadata and tests already performed. Share account details only through an appropriate private support route. State what remains unknown.
There is no universal percentage difference that makes a report safe to use. A small unexplained gap may matter for one decision, while two substantially different totals may both be valid for different questions. Make the reporting decision from the definition, evidence and intended use.
The investigation record below is designed to keep that reasoning visible. Leave unavailable evidence explicitly marked as unavailable. Close the investigation when you can explain the result and its use, or record who owns the unresolved question and the next check.
Sources8 references
Evidence & further reading
Google documentation checked 17 September 2026. The diagnostic sequence is an editorial synthesis, not an audit of an analytics account.
- 01
- 02
Google
Understand user metrics - 03
Google
DateRange - 04
- 05
- 06
Google
RunReportResponse - 07
Google
ResponseMetaData - 08
Google
Data freshness