LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Blog-Übersicht /Digital Analytics / BigQuery-Backfill-Grenze und Google-Signals-Reichweite: Zwei GA4-Änderungen aus dem...
Diesen Artikel in anderen Sprachen lesen:

BigQuery-Backfill-Grenze und Google-Signals-Reichweite: Zwei GA4-Änderungen aus dem Juni 2026

BigQuery-Backfill-Grenze und Google-Signals-Reichweite: Zwei GA4-Änderungen aus dem Juni 2026
Inhalt
  1. BigQuery-Backfill-Grenze und Google-Signals-Reichweite: Zwei GA4-Änderungen aus dem Juni 2026
  2. 1. Die Backfill-Grenze betrifft Reporting-Konnektoren
  3. 2. Kalenderdaten vor der Planung prüfen
  4. 3. Einen Wiederherstellungspunkt je Lauf sichern
  5. 4. Alle Tage vergleichen und danach Inhalte prüfen
  6. 5. Google Signals und Consent Mode steuern unterschiedliche Vorgänge
  7. 6. Einstellungen und Messnachweise getrennt erfassen
  8. Fragen und Antworten
  9. Quellen

BigQuery-Backfill-Grenze und Google-Signals-Reichweite: Zwei GA4-Änderungen aus dem Juni 2026

Zwei Änderungen aus dem Juni 2026 benötigen getrennte Prüfungen. Der BigQuery Data Transfer Service begrenzt historische Nachladungen mehrerer Reporting-Konnektoren auf 37 Monate. Google Signals steuert inzwischen eine enger gefasste Verknüpfung von Analytics-Daten; Ads Consent Mode regelt die zugehörige Erfassung und Nutzung von Werbedaten. Ein grünes Dashboard reicht für die Beurteilung beider Änderungen nicht aus.

1. Die Backfill-Grenze betrifft Reporting-Konnektoren

Ein Backfill lädt einen historischen Zeitraum erneut. Die BigQuery Release Notes vom 6. Mai 2026 kündigten an, dass die Data-Transfer-Service-Konnektoren für Google Ads, Search Ads 360 und Google Analytics 4 ab dem 1. Juni 2026 Backfills jenseits von 37 Monaten nicht mehr befüllen. Betroffen sind diese Konnektoren, einschließlich des GA4-Reporting-Datenkonnektors. Daraus folgt weder eine neue Aufbewahrungsgrenze für den nativen GA4-Export events_* noch eine automatische Löschung vorhandener BigQuery-Historie.

Das aktuelle Änderungsprotokoll unterscheidet die Ergebnisse: Google Ads und Search Ads 360 lehnen tägliche Nachladungen jenseits von 37 Monaten mit einem Fehler ab. Beim Analytics-Konnektor besteht dagegen das dokumentierte Risiko, historische Partitionen mit teilweisen oder leeren Ergebnissen zu überschreiben.

Die Grenze täglicher Transfers gilt nicht pauschal für sämtliche Google-Ads-Berichte. Monats-, Quartals- und Jahresberichte bleiben bis zu elf Jahre verfügbar; für Reichweiten- und Häufigkeitsmetriken gilt eine Grenze von drei Jahren.

Direkte Google-Ads-API-Abfragen jenseits von 37 Monaten benötigen mindestens monatliche oder keine Datumssegmentierung und einen Zeitraum aus vollständigen Monaten. Tagesdetails lassen sich aus diesen Aggregaten nicht rekonstruieren. API-Zeiträume beziehen sich auf customer.time_zone des ausliefernden Kontos. Das folgende UTC-Beispiel veranschaulicht die Kalenderrechnung und benötigt eine Anpassung an den konkreten Konnektor und dessen Zeitplanung; eine vollständige Prüfung beliebiger Google-Ads-API-Abfragen ist damit nicht umgesetzt.

Vor dem Backfill: Zeitraum prüfen und Snapshot sichern. Nach Abschluss: Zahlen und Inhalte vergleichen. Die neue Grenze löscht vorhandene Historie nicht automatisch.
Vor dem Backfill: Zeitraum prüfen und Snapshot sichern. Nach Abschluss: Zahlen und Inhalte vergleichen. Die neue Grenze löscht vorhandene Historie nicht automatisch.

2. Kalenderdaten vor der Planung prüfen

Die Grenze verschiebt sich mit dem Planungsdatum. Ein gespeicherter Zeitraum benötigt unmittelbar vor der Ausführung eine neue Prüfung, besonders nach Verzögerungen oder Wiederholungen. Das folgende Python-Gate verwendet UTC und begrenzt Monatsenddaten wie BigQuery DATE_SUB mit MONTH auf den letzten gültigen Tag. Der 31. März 2026 minus 37 Monate ergibt beispielsweise den 28. Februar 2023. GNU date kann das ungültige Februardatum stattdessen in den März verschieben; die alte Shell-Rechnung ist daher kein gleichwertiger Ersatz.

#!/usr/bin/env python3
import calendar
from datetime import date, datetime, timezone
import json
import re
import sys

def parse_day(value):
    if not re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", value):
        raise ValueError('Expected YYYY-MM-DD')
    return date.fromisoformat(value)

def months_before(day, months):
    month_index = day.year * 12 + day.month - 1 - months
    year, zero_month = divmod(month_index, 12)
    month = zero_month + 1
    return date(year, month, min(day.day, calendar.monthrange(year, month)[1]))

def validate(start_text, end_text, as_of):
    start, end = parse_day(start_text), parse_day(end_text)
    boundary = months_before(as_of, 37)
    if start > end:
        raise ValueError('Start is after end')
    if end > as_of:
        raise ValueError('End is in the future')
    if start < boundary:
        raise ValueError(f'Start precedes 37-month boundary {boundary}')
    return {'start': str(start), 'end': str(end),
            'as_of_utc': str(as_of), 'boundary': str(boundary)}

def main():
    if len(sys.argv) != 3:
        print('Usage: guard.py START END', file=sys.stderr)
        return 2
    try:
        result = validate(sys.argv[1], sys.argv[2], datetime.now(timezone.utc).date())
    except ValueError as exc:
        print(f'BLOCKED: {exc}', file=sys.stderr)
        return 1
    print(json.dumps(result))
    return 0

if __name__ == '__main__':
    sys.exit(main())

Das Beispiel prüft vollständige YYYY-MM-DD-Daten, Start vor oder gleich Ende, kein zukünftiges Ende und die 37-Monats-Grenze. Das Skript gibt den erlaubten Zeitraum aus, startet aber keinen Transfer. Der Scheduler muss bei einem Exit-Code ungleich null abbrechen und exakt die geprüften Daten an den eigentlichen Transferbefehl übergeben. Die UTC-Annahme und kontospezifische Planungsregeln benötigen nahe der Grenze eine Prüfung; ein Sicherheitspuffer kann Grenzfälle vermeiden. Dieses Gate gilt nur für die betroffenen Konnektoren, nicht pauschal für jeden Backfill.

3. Einen Wiederherstellungspunkt je Lauf sichern

Vor einer überschreibenden Nachladung müssen Ziel und Sicherung eindeutig feststehen. Die folgende Anweisung erstellt einen schreibgeschützten Tabellen-Snapshot. CREATE TABLE AS SELECT würde dagegen eine materialisierte Kopie anlegen. PROJECT, DATASET, TARGET_TABLE und RUN_ID sind Platzhalter; jeder Lauf benötigt eine neue RUN_ID. Snapshot und Quelle müssen am selben Standort liegen. Ein erfolgreich abgeschlossener Sicherungsjob ist Voraussetzung für den Transferstart.

-- Replace identifiers; use a fresh RUN_ID for every backfill.
-- Keep snapshot and source in the same location.
CREATE SNAPSHOT TABLE `PROJECT.audit.TARGET__RUN_ID`
CLONE `PROJECT.DATASET.TARGET_TABLE`;

Der Snapshot umfasst die Quelltabelle und keinen über WHERE ausgewählten Zeitraum. Daten im Streaming-Puffer und weitere Snapshot-Einschränkungen benötigen eine Prüfung für die konkrete Tabelle. Andere Schreibzugriffe auf den betroffenen Zeitraum müssen während des Vergleichs pausieren oder nachvollziehbar berücksichtigt werden. Vorhandene Snapshot-Namen dürfen nicht überschrieben werden. Eine Wiederherstellung in eine separate Tabelle sollte vor dem Ernstfall erprobt sein.

4. Alle Tage vergleichen und danach Inhalte prüfen

Nach Abschluss des Transfers vergleicht die Query den konkreten Snapshot mit der aktuellen Tabelle. Die vollständige Tagesliste enthält auch leere Tage. Eine fehlende Tabelle führt zum Abfragefehler statt zu null Zeilen; eine fehlende Tagesgruppe innerhalb einer vorhandenen Tabelle bedeutet für diese Abfrage tatsächlich null. Das Beispiel setzt PARTITION_DATE als DATE-Spalte voraus. Bei Ingestion-Time- oder Timestamp-Partitionierung ist ein ausdrücklich passender Datumsausdruck erforderlich.

-- Run only after the transfer has completed successfully.
-- @start_day and @end_day are DATE parameters from the validated range.
-- PARTITION_DATE is a DATE column in this example.
WITH days AS (
  SELECT day FROM UNNEST(GENERATE_DATE_ARRAY(@start_day, @end_day)) AS day
), before_counts AS (
  SELECT PARTITION_DATE AS day, COUNT(*) AS n
  FROM `PROJECT.audit.TARGET__RUN_ID`
  WHERE PARTITION_DATE BETWEEN @start_day AND @end_day
  GROUP BY day
), after_counts AS (
  SELECT PARTITION_DATE AS day, COUNT(*) AS n
  FROM `PROJECT.DATASET.TARGET_TABLE`
  WHERE PARTITION_DATE BETWEEN @start_day AND @end_day
  GROUP BY day
)
SELECT d.day,
       COALESCE(b.n, 0) AS rows_before,
       COALESCE(a.n, 0) AS rows_after,
       COALESCE(a.n, 0) - COALESCE(b.n, 0) AS delta,
       CASE
         WHEN COALESCE(b.n, 0) = 0 AND COALESCE(a.n, 0) = 0 THEN 'BOTH_EMPTY'
         WHEN COALESCE(a.n, 0) < COALESCE(b.n, 0) THEN 'FEWER_ROWS'
         WHEN COALESCE(a.n, 0) > COALESCE(b.n, 0) THEN 'MORE_ROWS'
         ELSE 'SAME_COUNT_REQUIRES_CONTENT_CHECK'
       END AS check_result
FROM days d
LEFT JOIN before_counts b USING (day)
LEFT JOIN after_counts a USING (day)
ORDER BY d.day;

Weniger Zeilen benötigen eine Untersuchung; mehr Zeilen sind ebenfalls eine Veränderung und kein automatischer Erfolg. Gleiche Zahlen beweisen keine gleichen Inhalte: Gelöschte Datensätze und neue Dubletten können sich rechnerisch ausgleichen. Prüfungen fachlicher Schlüssel, relevanter Kennzahlen und ausgewählter Einzelwerte bleiben notwendig. Der Snapshot bleibt bis zum Abschluss dieser Prüfung und des vorgesehenen Wiederherstellungsfensters erhalten. Eine unveränderte Zeilenzahl allein rechtfertigt keine Löschung.

5. Google Signals und Consent Mode steuern unterschiedliche Vorgänge

Laut Googles Hinweis zu Datenkontrollen steuern die Signals-Einstellung in der Analytics-Verwaltung und die zugehörige API seit dem 15. Juni 2026 nur noch die Verknüpfung von Analytics-Daten mit Informationen aus angemeldeten Nutzerkonten für das Verhaltens-Reporting. Die zugehörige Änderung überträgt die Kontrolle über Google-Ads-Cookies und Kennungen aus Analytics-Tag oder SDK an Ads Consent Mode. Gemeint ist dieser Werbedatenbereich, nicht die Gesamtheit aller Analytics-Daten.

Die Consent-Typen bleiben getrennt: ad_storage betrifft Werbe-Cookies oder Gerätekennungen; analytics_storage betrifft Analytics-Speicherung; ad_user_data betrifft die Übermittlung von Nutzerdaten für Onlinewerbung; ad_personalization steuert personalisierte Werbung. Eine Signals-Einstellung ersetzt diese Signale nicht. Je nach einfacher oder erweiterter Implementierung können trotz verweigerter Speicherung cookielose Mess-Pings auftreten. Ein denied-Wert bedeutet nicht grundsätzlich, dass keinerlei Netzwerkanfrage erfolgt.

6. Einstellungen und Messnachweise getrennt erfassen

Eine Bestandsaufnahme je Property kann Erfassungszeit, Property-ID, Signals-Zustand und Herkunft der Beobachtung festhalten. Die dokumentierte lesende Admin-API-Anfrage benötigt ein gültiges Access Token, den Scope analytics.readonly und Zugriff auf die Property. PROPERTY_ID und ACCESS_TOKEN sind Platzhalter; diese GET-Anfrage ändert keine Einstellung.

GET /v1alpha/properties/PROPERTY_ID/googleSignalsSettings HTTP/1.1
Host: analyticsadmin.googleapis.com
Authorization: Bearer ACCESS_TOKEN
Accept: application/json

Beispielantwort zur Erläuterung, keine Messung einer tatsächlichen Property:

{
  "name": "properties/123456789/googleSignalsSettings",
  "state": "GOOGLE_SIGNALS_ENABLED",
  "consent": "GOOGLE_SIGNALS_CONSENT_CONSENTED"
}

Das Feld consent dieser Ressource bedeutet Zustimmung zu den Google-Signals-Nutzungsbedingungen, nicht Einwilligung von Websitebesuchern. Ein fehlender oder unspecified-Zustand belegt keine Aktivierung. Fehlgeschlagene Anfragen müssen als Fehler erkennbar bleiben; eine geplante Inventur darf nicht lediglich einen Fehler anhängen und anschließend Erfolg melden. Ein Vergleich benötigt zwei erfolgreiche datierte Beobachtungen derselben Property. Diese Anfragevorlage implementiert keine automatische Inventur oder Differenzbildung.

Consent-Raten benötigen eine getrennte Definition der Zähleinheit: Ereignisse, Sitzungen und einzelne Einwilligungsentscheidungen ergeben unterschiedliche Quoten. Im nativen GA4-Export verwendet privacy_info.ads_storage die Werte Yes, No und Unset statt granted/denied. Unbekannte Werte gehören in eine eigene Kategorie. Eine veränderte Rate kann durch Traffic-Mix, Banneränderungen oder Releases entstehen; ein zeitlicher Zusammenhang mit Juni beweist keine Verursachung durch Signals.

Fragen und Antworten

Kann Time Travel eine Sicherung ersetzen?

BigQuery Time Travel kann eine Wiederherstellung innerhalb des konfigurierten Fensters ermöglichen: standardmäßig sieben Tage, einstellbar zwischen zwei und sieben Tagen. Ein Snapshot kann den Wiederherstellungspunkt länger erhalten. Snapshot-Speicherkosten können steigen, wenn Quellblöcke geändert oder gelöscht werden; kleine logische Änderungen können größere physische Blöcke betreffen. Weder dauerhaft geringe Kosten noch unbegrenzte nachträgliche Wiederherstellung sind vorauszusetzen.

Beweist ein unveränderter Änderungszeitpunkt einer Partition unveränderte Daten?

Nein. Metadaten aus INFORMATION_SCHEMA.PARTITIONS liefern hilfreichen Kontext. Bestimmte Änderungen, darunter Datensatzlöschungen, können jedoch in last_modified_time fehlen. Zählungen, Inhaltsprüfungen und ein tatsächlicher Wiederherstellungspunkt erfüllen unterschiedliche Aufgaben. Ein einzelnes Metadatenfeld beweist keine Vollständigkeit.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Kontakt

Eine Frage oder eine Idee für ein Webprojekt? Schreib mir kurz, worum es geht. Das Formular nutzt reCAPTCHA zum Schutz vor Spam.

Kommentar schreiben

Abweichende Zahlen aus anderen Konten und Rückfragen zur Einrichtung sind hier willkommen.

Die E-Mail-Adresse wird nicht veröffentlicht. Pflichtfelder sind mit einem Stern versehen.