A dashboard screenshot taken yesterday can become evidence in a budget meeting today. That is where Google Analytics 4 (GA4) BigQuery reporting stops being a query problem and becomes an accountability problem. The number may have been correct for the data available at the time and still need to change later.
Google documents two facts that force that distinction. Daily events_YYYYMMDD tables can receive late events after their first appearance, while streaming events_intraday_YYYYMMDD tables are temporary and best effort. Google also allows exceptional historical reprocessing after the ordinary late-arrival period. A daily table therefore is not a promise of permanent immutability. Google Analytics: BigQuery Export schema, living documentation, accessed September 15, 2026 and Google Analytics: BigQuery Export, living documentation, accessed September 15, 2026 establish those boundaries.
This runbook is for analysts, analytics engineers, marketing analysts, business-intelligence owners and reporting managers who need evidence for publishing or revising a metric. It treats source selection, observation time, metric definitions, late-arrival replay, historical correction and stakeholder communication as one control system. The operating model below is proposed, not a Google requirement. Its purpose is simple: every published number should be reproducible from a named source state, a named metric definition and an approval decision.
Define what a published number promises
A published metric should promise less than “truth forever” and more than “whatever the query returned.” The practical contract is: this metric, for this reporting date, was computed from these accepted sources, under this definition, observed at this time, and approved for this use. That language survives late data because it separates evidence from permanence.
For GA4 BigQuery late arrivals, I use three local statuses. Provisional means a number is useful for monitoring but still exposed to source replacement or routine late arrivals. Approved means the agreed observation and quality gates passed. Revised means an approved number was later replaced through an accountable correction process. These are governance labels, not GA4 fields.
Local status | Publication promise | Permitted use | Required evidence | Owner |
Provisional | Best available observation, still changeable | Operational monitoring, clearly labeled | Source type, event date, observation time, metric version | Analyst on duty |
Approved | Passed source, definition and completeness gates | Recurring management reporting | Daily-source evidence, query revision, comparison result, approver | BI/reporting owner |
Revised | Prior approved result superseded | Corrected reporting and downstream restatement | Previous value, new value, reason, approval, notice | Metric owner |
The consumer matters. A marketing pacing view can tolerate provisional current-day counts that a board pack should not. This discipline complements broader GA4 in search-marketing measurement, but the control here is narrower: do not let a dashboard’s visual polish imply stronger completeness than its source state supports. The linked Refonte article discusses GA4 and reporting as part of broader search-marketing practice rather than this restatement workflow.
Publishing checklist: name the consumer, metric, property-local reporting date, current status, allowed use, observation timestamp, metric-definition version and approver before a value is called “final.” In this runbook, “approved” is safer wording than “final” because Google documents later historical reprocessing.
Inventory property settings and export dependencies
Do not troubleshoot completeness until you can describe the export you expect. At minimum, record the GA4 property ID, registered property timezone, BigQuery dataset, enabled export types, whether the property is Standard or Analytics 360, relevant streams or export filters, and the downstream query revision. Google’s schema documents the dataset pattern analytics_<property_id>, while the export overview distinguishes Daily, Streaming and Fresh Daily options.
Tier matters. Google currently states that Standard properties have a daily BigQuery Export limit of one million events, while Streaming is best effort and has no completeness service-level objective (SLO). The 360 completeness signal described later is not a Standard-property feature. Treat those as scoped product facts, not as general behavior for every GA4 property.
Inventory item | Evidence to record | Why it changes interpretation | Escalation owner |
Property and dataset | Property ID; analytics_<property_id> dataset | Prevents cross-property comparisons | Analytics admin |
Timezone | Current registered property timezone and change history | Governs table-update calendar and date interpretation | Analytics admin |
Export options | Daily, Streaming, Fresh Daily if applicable | Determines which source tables/signals can exist | Analytics engineer |
Property tier | Standard or 360 | Changes limits and completeness-signal availability | Platform owner |
Export filters/streams | Current configuration and effective date | Can explain missing populations | Measurement owner |
Reporting SQL | Repository revision or immutable query ID | Distinguishes changed data from changed logic | Analytics engineer |
Google warns that changing the property timezone can affect BigQuery export behavior, including discrepancies or a skipped daily export. That makes timezone configuration operational metadata, not a cosmetic setting. Google Analytics: BigQuery Export, accessed September 15, 2026 ties table updates to the property timezone.
Stop condition: when a required daily table is absent, assign a source incident owner before anyone substitutes zero. The reporting owner decides whether the report remains unpublished, carries a provisional warning, or excludes the affected date. The analytics administrator investigates configuration; the analytics engineer preserves query and table evidence.
Separate the three clocks in the reporting pipeline
Three different clocks often get collapsed into one field called “date.” That is how a defensible GA4 SQL report turns into an argument about whose screenshot is correct.
The first clock is the property-local event date represented by event_date. The second is the documented event_timestamp, which Google defines as the UTC microsecond time when the event was received by Google Analytics. The third is yours: observation and publication time, such as when an orchestration job queried BigQuery, staged a candidate metric and obtained approval. Google Analytics: BigQuery Export schema, accessed September 15, 2026 defines the first two; the third belongs in your reporting metadata.
Clock | Source or owner | Meaning | Do not assume |
event_date | GA4 export | Date logged in the registered app/property timezone | It equals UTC date |
event_timestamp | GA4 export | Microseconds UTC when GA received the event | It is a unique event key |
Observation time | Local reporting system | When this team inspected or extracted the source | GA4 supplies it |
Approval time | Local governance | When a candidate became publishable | Source data became immutable |
Event date and event timestamp are not interchangeable
Google explicitly notes that multiple events can share the same event_timestamp, including events sent in the same request. Therefore, never deduplicate all GA4 events on event_timestamp alone. The schema also exposes ordering and batch fields, but it does not give you permission to invent a universal cross-implementation event key from one timestamp.
A useful synthetic boundary fixture uses a hypothetical property timezone of Europe/Berlin. For an immediately delivered event on September 10, 2026, compare a UTC timestamp just before local midnight with one just after. The acceptance test is not “recompute every event_date from event_timestamp.” It is “confirm that your SQL groups by the intended property-local date and does not silently apply UTC dates.” Late events make the distinction even more important because receipt time and logged event date can diverge.
Export observation time and reporting cutoff
Observation time is the missing control in many marts. Suppose events_20260910 contains 973 purchase rows when queried at 13:00 property time on September 11 and 981 at the same time on September 12. Both observations can be valid evidence. The second should not erase the fact that the first was what the organization had previously seen.
Record observed_at_utc, source_table_set, source_state, query_revision and metric_definition_version beside the candidate result. These are proposed local fields. They let you say “the source changed” separately from “the SQL changed.” That distinction becomes the spine of the restatement ledger.
Acceptance checklist: for every metric date, preserve the property timezone, event-date basis, source table names, extraction timestamp and query revision. Reject a candidate whose timezone assumption cannot be resolved.
Choose one authoritative source for each date and status
For a given intended population, do not casually union events_* and assume BigQuery will protect you from overlap. Google says Streaming creates events_intraday_YYYYMMDD, that the intraday table is temporary, and that it is deleted when the daily events_YYYYMMDD table is complete. Google recommends querying the daily table rather than intraday for a stable day-level dataset. Streaming itself is best effort and may contain gaps.
My proposed source policy is deterministic. For the current property-local date, use intraday only in a clearly provisional path. For a closed date, use the daily table when it exists. Never create one “authoritative” date result by adding both daily and intraday rows for the same date.
Reporting date state | Preferred source | Local status | Publication rule | If source missing |
Current property-local day | events_intraday_YYYYMMDD if Streaming enabled | Provisional | Label as incomplete/current-day | Show unavailable, not zero |
Prior day before daily appears | No substitute for approved reporting; optional intraday view if retained and valid | Provisional | Keep out of approved daily mart | Escalate expected-table check |
Prior day with daily table | events_YYYYMMDD only | Provisional or approved | Rebuild inside replay policy | Compare with prior observation |
Older approved date | Daily table | Approved | Do not rebuild routinely outside policy | Use exception process if source changes |
This is an operating choice, not a vendor guarantee. Google calls the daily export a complete set for the previous day in its export-type table, yet the same documentation says daily tables continue to receive late events during the ordinary update window and may be changed later by exceptional reprocessing. Read “daily” as source type, not “immutable.”
A safe wildcard must also distinguish suffix shape. events_* can match daily and intraday table names. Filtering TABLESUFFIX to exactly eight digits is one simple way to constrain a daily-only scan when your naming pattern is standard. Google’s Basic queries for Google Analytics event data export, updated June 15, 2026 documents TABLESUFFIX filtering for date ranges.
Stop condition: block publication when source selection can double-count intraday and daily data, or when a required daily table is absent. Resolve source identity before examining the metric value.
Model routine late arrivals and exceptional corrections
Google’s living schema says daily event tables can be updated with late events for up to three days after the event dates. The export overview expresses the ordinary rule as updates for “2 calendar days, plus today” beyond the table date and gives an example in which a January 1 table may be updated through January 4. That wording is calendar-based, not a universal fixed 72-hour SLO.
There is an important second rule: Google says Analytics may occasionally update daily tables after that ordinary window when historical data must be reprocessed, for example after a bug fix. Therefore, “three days have passed” can justify ending your routine replay process, but it cannot justify claiming the provider table is permanently frozen.
I recommend two lanes: a bounded routine replay lane and an exceptional correction lane. The exact schedule below is a proposed local choice, not a Google requirement.
Source condition | Proposed local transition | Typical action | Approval needed |
Current-day intraday | Open → Provisional | Refresh monitor only | No formal restatement |
First daily observation | Provisional → Daily-observed | Replace intraday-derived candidate | Normal daily control |
Daily table changes inside routine window | Daily-observed → Provisional-updated | Rebuild affected dates | Normal approval |
Routine window closes with checks passed | Provisional-updated → Approved | Publish accepted date | Reporting owner |
Older approved date changes | Approved → Exception-pending | Stage historical correction | Metric owner + reviewer |
Exception accepted | Exception-pending → Revised | Publish revision and notice | Named approver |
Do not use GA4 report freshness guidance as a BigQuery delivery guarantee. Google’s Data freshness documentation, accessed September 15, 2026 says report processing can take 24–48 hours and that report data may change; it also labels its typical prior-day timing as non-guaranteed. That is context for reporting surfaces, not a completeness SLO for every BigQuery table.
Decision rule: routine late arrival is “expected source evolution inside the locally defined replay period.” Exceptional correction is “an older accepted date changed or must be recomputed outside that period.” The second path requires provenance and stakeholder review even when the numerical change is small.
Build a repeatable date-level reporting mart
Build restatement logic in a derived dataset, not by editing Google-managed export tables. The reporting mart should be reproducible from raw daily exports plus a versioned metric definition. General data warehouse management foundations are useful context, but this control is specific: validate source availability, stage a bounded rebuild, compare it with the currently approved output, then publish only the accepted differences. The linked Refonte article covers broader warehouse practice.
Before reading event rows, use metadata. BigQuery’s INFORMATION_SCHEMA.TABLES view is read-only metadata with one row per table or view in a dataset. That makes it suitable for proving whether a required events_YYYYMMDD table exists before a report interprets a missing table as zero activity. Google Cloud: TABLES view, living documentation, accessed September 15, 2026 documents that scope.
Mart layer | Purpose | Mutation policy | Evidence retained |
Raw GA4 export | Provider-managed source | Read only | Table names and observation time |
Candidate staging | Rebuild affected dates | Replaceable | Query revision, source range, counts |
Comparison | Diff candidate vs approved | Append-only result preferred | Old/new/delta and test outcome |
Approved mart | Consumer-facing metric | Controlled DML only | Publication revision/status |
Restatement ledger | Governance trail | Append-only local record | Reason, approver, timestamps |
Bounded rebuilds without intraday double-counting
The following unexecuted GoogleSQL example uses placeholders and counts exported rows where event_name = 'purchase'. It does not deduplicate events and does not calculate revenue. The regular expression excludes intraday_YYYYMMDD suffixes.
-- UNEXECUTED EXAMPLE. Replace PROJECT, analytics_PROPERTY, and dates.
BEGIN
IF (
SELECT COUNT(*)
FROM PROJECT.analytics_PROPERTY.INFORMATION_SCHEMA.TABLES
WHERE REGEXP_CONTAINS(table_name, r'^events_2026091[0-3]$')
) != 4 THEN
RAISE USING MESSAGE = 'Required GA4 daily table is missing';
END IF;
CREATE OR REPLACE TABLE PROJECT.reporting_stage.purchase_event_daily_candidate AS
SELECT PARSE_DATE('%Y%m%d', event_date) AS event_date,
COUNTIF(event_name = 'purchase') AS purchase_event_count
FROM PROJECT.analytics_PROPERTY.events_*
WHERE REGEXP_CONTAINS(_TABLE_SUFFIX, r'^\d{8}$')
AND TABLESUFFIX BETWEEN '20260910' AND '20260913'
GROUP BY event_date;
EXCEPTION WHEN ERROR THEN
SELECT @@error.message AS build_error;
RAISE;
END;Google’s current query guide uses TABLESUFFIX for bounded event-table scans, while Google Cloud: Procedural language, updated September 15, 2026 documents exception handling and RAISE. The control objective is not clever SQL; it is making missing-source failure explicit before a staged result can be mistaken for complete.
Restatement ledger and publication revision
A local ledger should carry at least: metric_name, metric_definition_version, source_date_start, source_date_end, observed_at_utc, query_revision, previous_result, candidate_result, delta, source_state, reason_code, approver, approved_at_utc, and a pointer to the correction notice. None of these is claimed to be a GA4 export column.
For publication, prefer a transaction or other atomic promotion mechanism so consumers do not see a partially replaced date range. BigQuery supports multi-statement transactions that commit or roll back mutating operations atomically. Google Cloud: Multi-statement transactions, living documentation, accessed September 15, 2026 documents that behavior.
Publish checklist: source table present; daily-only population confirmed; candidate row count sensible; metric version unchanged; old/new diff reviewed; ledger row prepared; transaction succeeds; only then update status to approved or revised.
Walk through the late-purchase-event example
Consider a fictional, synthetic purchase-event mart for a hypothetical GA4 property in Europe/Berlin. The metric definition is version purchase_event_count_v1: count one exported row for every daily-table event whose event_name = 'purchase', grouped by event_date. It is an event count, not unique transactions and not recognized revenue.
The reporting date is September 10, 2026. The metric definition stays fixed throughout the example. Only source state and observation time change.
Observation | Source chosen | Synthetic count | Arithmetic vs prior | Local status |
Sep 10, 18:00 local | events_intraday_20260910 | 941 | Initial | Provisional |
Sep 11, 13:00 local | events_20260910 | 973 | +32 vs intraday | Daily-observed |
Sep 12, 13:00 local | events_20260910 | 981 | +8 late rows | Provisional-updated |
Sep 14, 13:00 local | events_20260910 | 981 | 0 | Approved |
Oct 7, 09:30 local | events_20260910 | 984 | +3 historical change | Exception-pending |
Oct 7, 11:00 local | Approved derived mart | 984 | +3 restatement | Revised |
The intraday-to-daily move is a source replacement, not a restatement of an approved number. The Sep 12 change is a routine late-arrival update under the local replay policy. The Sep 14 approval is a governance decision after the ordinary calendar window has passed; it is not evidence that the source can never change. Google explicitly allows later historical reprocessing.
The October change is different. The September 10 metric was already approved at 981. A new source observation now produces 984 under the same metric version and same SQL revision. Because the source changed by three rows while logic stayed constant, the ledger can classify the candidate as a source-data restatement rather than a definition change.
A concise correction notice could read: “Purchase-event count for September 10, 2026 was revised from 981 to 984 (+3; +0.31%) after a later change in the GA4 daily export was detected. Metric definition purchase_event_count_v1 and query revision abc123 were unchanged. The revised value was approved October 7 at 11:00 property time. This metric counts GA4 purchase events and is not an accounting revenue measure.” The percentage is synthetic arithmetic: 3 / 981 × 100 ≈ 0.31%.
Acceptance question | Expected evidence | Example outcome |
Did the source change? | Earlier and later observations of same daily table | Yes, 981 → 984 |
Did SQL change? | Same immutable query revision | No |
Did metric definition change? | Same definition version | No |
Is the old value already approved? | Ledger status before new observation | Yes |
Is revision provenance complete? | Reason, approver, affected reports | Yes before publish |
That matrix is the practical heart of GA4 reporting restatement: changed data, changed SQL and changed definitions are different incidents and should never share one vague “dashboard updated” explanation.
Detect missing exports before diagnosing low activity
A missing table and a table containing zero matching events are not the same observation. The first says the source expected for that reporting date is absent. The second says a source table exists and your defined population returned zero. Treating both as zero destroys the evidence needed to diagnose the incident.
Start with a read-only metadata check. BigQuery INFORMATION_SCHEMA.TABLES can establish whether the expected table exists. Google also documents that Standard daily exports are capped at one million events per day and that export filtering may be used to stay under that limit; comparison guidance notes that filtering and export limits can produce differences from GA4 reporting surfaces.
-- UNEXECUTED READ-ONLY CHECK. Replace PROJECT and analytics_PROPERTY.
SELECT
table_name,
table_type,
creation_time
FROM PROJECT.analytics_PROPERTY.INFORMATION_SCHEMA.TABLES
WHERE table_name IN ('events_20260914', 'events_intraday_20260914');Symptom | First evidence | Plausible class | Publish action |
Expected daily table absent | Metadata shows no table | Export delay/configuration/link issue | Block approved publication |
Daily table exists, zero purchases | Table exists; purchase filter returns zero | Genuine zero or instrumentation issue | Investigate event population |
Daily total suddenly truncated | Compare overall events and configuration | Export limit/filter change | Escalate before interpreting trend |
Downstream mart missing but source exists | Job history/query logs | Transformation failure | Rebuild derived layer |
Date after timezone change missing | Property change record + export metadata | Timezone-related export effect | Escalate, do not backfill zero |
Google says property-timezone changes can lead to export discrepancies or a skipped daily export. It also says Streaming is best effort and may contain gaps. Those documented behaviors are why “the dashboard is low” is not a diagnosis.
Use an evidence-first escalation order: source existence → configuration/tier → raw event volume → metric filter → transformation job → dashboard cache or semantic layer. This order prevents a BI owner from wasting time tuning a chart when the source table never arrived.
Hard stop conditions: required daily source absent; daily/intraday overlap unresolved; metric version changed without review; property timezone unresolved; or candidate revision has no provenance. In each case, retain the previous approved derived output and label the affected new period unavailable or provisional. Do not write fabricated rows into Google-managed export tables.
Reconcile with GA4 reports without forcing equality
A GA4 BigQuery data discrepancy is not automatically a pipeline defect. Google’s export overview says BigQuery exposes raw event and user-level data without some value additions used in standard reports and explorations. Google’s developer comparison discusses modeling, Google Signals, attribution, sampling or approximation, high-cardinality handling, reporting identity, metric scope, timezone, filtering and export limits as reasons comparisons can diverge.
Google Analytics / Minhaz Kazi: Bridge the gap between the Google Analytics UI and BigQuery export, article dated April 2023; page updated June 15, 2026 is therefore a reconciliation guide, not a promise of equality.
This is especially important in first-party marketing measurement: the business may compare a warehouse metric with a marketer’s GA4 report, but both teams must first agree on what is actually being counted. The linked Refonte article provides broader first-party measurement context, not authority for GA4 export semantics.
Reconciliation item | BigQuery evidence | GA4-report evidence | Decision |
Date range/timezone | event_date, property timezone | Report date range/timezone | Align before comparing |
Metric definition | SQL and scope | UI metric name/definition | Map exact population |
Identity | user_id/user_pseudo_id logic | Reporting identity setting | Expect differences if not equivalent |
Modeling/signals | Raw export limitations | Modeled/reporting behavior | Record as legitimate scope difference |
Filters/limits | Export configuration | Report filters | Confirm both sides |
Observation time | Extraction timestamp | Screenshot/report retrieval time | Avoid comparing different source states |
Google notes that event_date uses the reporting timezone while event_timestamp is UTC. It also states that modeled data from Consent Mode is not available in the BigQuery event export and that Google Signals can change user deduplication in reporting surfaces without exposing the same signal in BigQuery.
The accountable response to an unresolved difference is “reconciliation incomplete; cause not yet isolated,” not “BigQuery is wrong” and not “the UI is wrong.” Never alter raw exported events merely to match a screenshot. Reconcile definitions, timing and value additions first; document the remaining variance and its business impact.
Test calendar changes and completeness signals
Completeness testing should use fixtures that attack calendar boundaries, source transitions and exception paths rather than only happy-path row counts. Build synthetic cases around local midnight, delayed receipt, a changed property timezone and a later historical source revision. Keep Standard and 360 expectations separate.
Google’s 360 completeness signal applies to Daily or Fresh Daily export for 360 properties and indicates when all of the previous day’s data has been exported for that export cycle. Google also warns that the signal may be missing or inaccurate on the first day after a property-timezone change or after the BigQuery link is created.
Synthetic fixture | Property tier | Expected control result | Failure means |
Event around local midnight | Standard or 360 | Group by intended property-local date | Timezone/date logic defect |
Late row inside ordinary window | Standard or 360 | Affected date rebuilds in replay | Replay coverage defect |
Daily table absent | Standard or 360 | Publication blocked | Missing-source control defect |
Completeness signal absent after timezone change | 360 | Treat signal cautiously; inspect source | Overreliance on first-day signal |
Old approved table later changes | Standard or 360 | Open exception restatement | Historical monitoring defect |
Timezone and late-arrival boundary cases
Use explicit dates. In a hypothetical Europe/Berlin property, test September 10 and September 11, 2026 around the local midnight boundary. Keep the timezone in the fixture definition, not hidden in a session default. Separately, inject a synthetic row assigned to September 10 but observed later in the ordinary update period; the acceptance condition is that September 10 is rebuilt and compared, not that it is discarded because “yesterday already closed.”
Do not replace Google’s calendar-day wording with a blanket “wait exactly 72 elapsed hours” rule. The current export overview says “2 calendar days, plus today,” while the schema summarizes late-table updates as up to three days after the event date. The safest local control is therefore property-calendar based and explicitly documented.
360 export completeness versus event-date stability
The 360 completeness signal is about export-day processing. Google says its event total can include events that occurred earlier but were received or backfilled later, and explicitly states that the signal reflects data flow for the export day rather than strictly the event’s original timestamp. That scope means the signal should not be treated as a permanent lock on every historical event-date table.
Pair two tests: first, verify that your 360 workflow recognizes the signal for the relevant export day when available; second, simulate or detect a later change in an already approved event-date table and require the exception path to open anyway. For Standard properties, do not wait for a 360-only signal that does not exist.
Acceptance rule: a completeness signal can satisfy one source-processing checkpoint. It cannot waive table-existence checks, metric-version checks, historical-change detection or correction provenance.
Communicate revisions and control access to evidence
Restatement quality is partly a communication discipline. A corrected dashboard with no notice leaves downstream users holding two conflicting screenshots and no way to establish which value was approved when.
Every correction notice should state the affected metric and date range, previous approved value, revised value, absolute and percentage change where meaningful, reason category, whether SQL or definition changed, approval time, approver and dependent reports that must refresh. Keep the language causal only to the level you can prove. “Source table changed” is defensible when observations show that; “Google bug” is not unless Google has documented the cause.
Notice field | Required content | Owner |
Scope | Metric, dates, reports affected | Reporting manager |
Values | Previous, revised, delta | Analyst |
Cause classification | Source change, SQL change, definition change, unresolved | Analytics engineer |
Provenance | Observation times, query revision, ledger ID | BI owner |
Approval | Approver and timestamp | Metric owner |
Distribution | Stakeholders and refresh instructions | Reporting manager |
This is also where data governance responsibilities matter: evidence access, retention and ownership should be explicit. The linked Refonte article is general governance context and should not be treated as legal authority.
The raw GA4 export can include identifiers such as user_id and user_pseudo_id when present. Keep public examples aggregated and synthetic, and restrict operational evidence according to your organization’s approved access model. Google’s schema documents those fields; it does not by itself establish your legal retention or disclosure obligations.
Communication checklist: publish the notice with the revised value; update dependent dashboards or extracts; annotate the restatement ledger; notify report owners; preserve the superseded approved value for audit; and state whether any business decision needs reconsideration. A correction notice is complete when a consumer can tell what changed, why, when and who approved it.
Recover the last approved report safely
The safest failure response is not to improvise against the raw export. Preserve the last approved derived result, isolate the failed candidate and restore service from the approved state while investigation continues.
Consider three failure classes. A rebuild job can fail halfway through. A query revision can unexpectedly change metric population. Or an older GA4 daily table can change after a report was approved. The recovery objective differs slightly, but the invariant is the same: never overwrite the evidence needed to compare old and new states.
Failure | Immediate action | Recovery target | Reapproval trigger |
Candidate rebuild fails | Stop promotion | Keep prior approved mart | Successful rerun + checks |
New SQL changes metric silently | Reject candidate | Restore prior query/output status | Definition/change review |
Historical source change detected | Freeze current approved view pending review | Keep old approved value visible or mark correction pending | Accepted exception restatement |
Partial publication attempt | Roll back atomic transaction | Last committed approved rows | Transaction succeeds after validation |
BigQuery supports transactions that can roll back mutating operations atomically, which is useful when replacing a bounded range in an approved table. A practical design can also keep versioned candidate tables or snapshots, but the exact retention mechanism is a local architecture choice.
The recovery sequence I recommend is: stop downstream promotion; capture the failed job/query revision; confirm the raw source has not been edited; restore or retain the previous approved derived output and its prior status; rerun source-existence and metric-definition checks; rebuild into staging; compare; obtain approval; then republish. Do not change a historical status from “approved” to “provisional” without preserving what was actually approved at that time.
Rollback checklist: previous approved version addressable; failed candidate preserved; ledger notes failure; consumer view points to approved state; source table untouched; root cause classified; new candidate independently compared; approver signs the re-release.
The boundary is deliberate. You own your derived reporting layer. Google manages the export tables it creates. Recovery should occur in your controlled layers rather than by editing provider-managed history to force agreement.
Build a reporting-quality portfolio
A strong reporting-quality artifact is not a screenshot of a green dashboard. It is a compact evidence package another analyst can review: source-selection policy, missing-table query, bounded rebuild SQL, synthetic fixture cases, metric-definition file, comparison output, restatement-ledger schema and one example correction memo.
Use a reviewer rubric that rewards traceability rather than complexity.
Reviewer question | Pass evidence | Owner for remediation |
Can I reproduce the metric definition? | Versioned SQL and definition text | Analytics engineer |
Can I prove which source tables were used? | Source manifest and observation time | Analyst |
Can I distinguish data change from logic change? | Ledger versions and diffs | BI owner |
Are failure and rollback paths explicit? | Runbook test and approved-state pointer | Reporting manager |
Is stakeholder communication reviewable? | Correction memo linked to revision | Metric owner |
That portfolio also clarifies marketing and analytics responsibilities: marketing can own the decision context while analytics owns reproducible definitions and evidence, with shared accountability for how revisions are communicated. The linked Refonte article discusses the broader distinction between the disciplines.
Learners who want structured practice in the underlying analytics foundations can review Refonte Learning’s Data Analytics Program. Its verified SQL, exploration, visualization and industry-project foundations map naturally to metric-definition, SQL-validation and reporting-evidence exercises.
The live page lists a three-month format, 12–14 hours per week and eligibility for people engaged in bachelor’s or postgraduate studies. It names Python for business analytics, exploratory data analysis and visualization, SQL databases, predictive modeling, problem-solving and industry projects; its educational path also names Tableau and advanced Excel. The page does not verify a GA4, BigQuery, GoogleSQL or late-arrival-restatement lab, so no such coverage is implied.
Owner-based next step: the analytics engineer versions source and metric logic; the analyst maintains observations and comparisons; the BI owner controls promotion; the reporting manager owns notices and dependent reports; the metric owner approves exceptions. One metric with this full evidence chain is more instructive than ten dashboards with undocumented freshness assumptions.
Answer the questions behind changing dashboards
The recurring questions are usually less technical than the pipeline that created them. Answer them with the narrowest claim the evidence supports.
Question type | Defensible answer basis | Escalate when |
“Why did yesterday change?” | Compare source observations, SQL revision and metric version | Cause class remains unresolved |
“Is this number final?” | State local status and evidence cutoff | Consumer requires stronger assurance |
“Why does GA4 differ?” | Reconcile definition, timing, identity/modeling and filters | Difference affects a material decision |
“Do we need a correction?” | Check whether an approved number changed materially or operationally | No owner can approve the threshold/impact |
Does a daily GA4 BigQuery table mean the number is final? No. The daily table is the preferred stable source for a closed day, but Google documents ordinary late updates to daily tables and exceptional historical reprocessing. “Daily” describes the export table, not permanent immutability.
Does the three-day late-arrival wording mean the table is immutable after exactly 72 hours? No. Google’s current documentation uses both “up to three days” and “2 calendar days, plus today” language. That supports a calendar-based routine replay boundary, not a universal elapsed-hour guarantee, and exceptional reprocessing can occur later.
Is Streaming export complete enough to publish as an approved daily number? Not by default. Google describes Streaming as best effort, without a completeness SLO, and says intraday tables may contain gaps. Use it for clearly provisional current-day reporting unless your local contract explicitly accepts those limitations.
Why can BigQuery and GA4 reports disagree even when both are working? BigQuery exports raw collected event/user-level data, while GA4 reporting surfaces can apply value additions and different counting behavior. Google’s comparison guidance discusses modeling, Signals, reporting identity, cardinality estimation, scope, timezone, filters and export limits among the causes.
When should we issue a correction notice? The proposed rule in this runbook is: issue one when a previously approved number is replaced and the change matters to a downstream report, decision or agreed materiality policy. Routine provisional updates before approval do not need to be described as restatements, but their status must be visible. The threshold for “material” is an organizational decision and should be documented rather than invented case by case.
The next useful contract to document is not “GA4 data is final after X hours.” Document one concrete combination: source date, source type, property timezone, metric definition, observation cutoff, approval owner and exception path. That contract is specific enough to test, explain and recover when yesterday’s number changes again.
