Eksport GA4 do BigQuery: kiedy ma sens i jak go uruchomić bez kosztów

26 października, 2026

Interfejs Google Analytics 4 wystarcza do codziennego podglądu ruchu, ale przy pierwszej poważniejszej analizie zaczyna się gubić: raport się próbkuje, długie listy stron zwijają się do wiersza „(other)”, a małe segmenty znikają za progami prywatności. Eksport GA4 do BigQuery omija te ograniczenia, bo daje dostęp do surowych zdarzeń zamiast gotowych agregatów. Konfiguracja zajmuje kilkanaście minut, a przy ruchu typowym dla bloga lub małego sklepu koszt na starcie wynosi zero. Ten tekst jest częścią serii o analityce marketingowej i pomiarze w GA4.

Trzy problemy GA4, które rozwiązuje eksport

Pierwszy problem to próbkowanie w eksploracjach. Gdy zapytanie obejmuje więcej zdarzeń, niż pozwala limit usługi standardowej, GA4 liczy wynik na podzbiorze danych i oznacza to zieloną lub żółtą tarczą. W BigQuery każde zapytanie liczy się na pełnym zbiorze.

Drugi problem to kardynalność. Wymiary o wielu unikalnych wartościach, takie jak adres strony z parametrami czy wyszukiwana fraza wewnętrzna, są w raportach obcinane, a nadwyżka trafia do „(other)”. Eksport zapisuje każdą wartość osobno, więc nic się nie skleja.

Trzeci problem to progi (thresholding). Przy włączonych Google Signals albo przy małych liczbach użytkowników GA4 ukrywa wiersze, żeby nie dało się zidentyfikować osoby. W surowych danych progów nie ma. Wszystkie trzy mechanizmy opisujemy szerzej w tekście o tym, czym są sampling, cardinality i thresholding w GA4.

Jest jeszcze czwarty, mniej oczywisty powód: retencja. Usługa standardowa przechowuje dane do eksploracji najwyżej 14 miesięcy. Tabele w BigQuery zostają tak długo, jak sami zdecydujemy.

Konfiguracja połączenia krok po kroku

Potrzebne są dwa uprawnienia: rola edytora w usłudze GA4 oraz rola właściciela w projekcie Google Cloud. Sama procedura wygląda tak:

  1. W konsoli Google Cloud utwórz projekt (albo wybierz istniejący) i włącz BigQuery API.
  2. Jeśli nie chcesz podpinać karty, zostań przy trybie piaskownicy BigQuery, który nie wymaga konta rozliczeniowego.
  3. W GA4 przejdź do Administracja, Połączenia usług, Połączenia z BigQuery i kliknij Połącz.
  4. Wskaż projekt i lokalizację danych. Wybierz region UE, jeśli dbasz o zgodność z RODO; lokalizacji nie da się później zmienić.
  5. Zaznacz strumienie danych do eksportu i, opcjonalnie, wyklucz zdarzenia, których nie potrzebujesz.
  6. Wybierz częstotliwość: dzienną, strumieniową albo obie.

Po zapisaniu GA4 dodaje do projektu konto usługi firebase-measurement@system.gserviceaccount.com i tworzy zbiór danych o nazwie analytics_ z numerem usługi. Pierwsza tabela pojawia się zwykle w ciągu doby. Szczegóły i aktualne limity Google opisuje w dokumentacji BigQuery Export.

Eksport dzienny kontra strumieniowy

Eksport dzienny raz na dobę zapisuje kompletną tabelę events_RRRRMMDD. Jest bezpłatny po stronie GA4, ale usługi standardowe mają limit miliona zdarzeń dziennie; przy regularnym przekraczaniu Google może wstrzymać eksport. Dla większości polskich blogów i sklepów to bardzo odległy sufit.

Eksport strumieniowy dopisuje zdarzenia do tabeli events_intraday_RRRRMMDD z kilkuminutowym opóźnieniem i nie ma limitu wolumenu. Kosztuje jednak 0,05 USD za gigabajt, czyli mniej więcej za 600 tysięcy zdarzeń, i nie działa w piaskownicy. Google zaleca też, by dane o atrybucji użytkownika czytać z eksportu dziennego, bo w strumieniu mogą być opóźnione nawet o 24 godziny. Strumień ma sens, gdy coś reaguje na dane w ciągu dnia: alerty, panel sprzedaży na żywo, automatyczne wstrzymywanie kampanii. Do raportowania wystarcza eksport dzienny.

CechaEksport dziennyEksport strumieniowy
Tabelaevents_RRRRMMDDevents_intraday_RRRRMMDD
Opóźnienieraz na dobękilka minut
Limit (usługa standardowa)1 mln zdarzeń dzienniebrak limitu wolumenu
Koszt po stronie GA4bezpłatny0,05 USD za GB
Piaskownica BigQuerydziałaniedostępny

Struktura tabeli zdarzeń i pola zagnieżdżone

Każdy wiersz to jedno zdarzenie. Najważniejsze kolumny to:

  • event_date, event_timestamp (w mikrosekundach) i event_name,
  • user_pseudo_id, czyli identyfikator przeglądarki, oraz user_id, jeśli go wysyłasz,
  • event_params, tablica par klucz i wartość, w której siedzą page_location, ga_session_id czy engagement_time_msec,
  • traffic_source (źródło pierwszej wizyty użytkownika), collected_traffic_source (parametry UTM zdarzenia) i session_traffic_source_last_click (źródło sesji),
  • device, geo, ecommerce i tablica items.

Pole event_params sprawia najwięcej kłopotu na początku. Wartość parametru leży w jednym z czterech podpól (string_value, int_value, float_value, double_value), a żeby ją wyciągnąć, trzeba użyć podzapytania z UNNEST. Sesja jako osobny wiersz nie istnieje; buduje się ją z pary user_pseudo_id i ga_session_id.

Darmowy poziom i realny koszt przy średnim ruchu

BigQuery daje co miesiąc bezpłatnie 10 GB przechowywania i 1 TB przetworzonych danych w zapytaniach (aktualne stawki są w cenniku BigQuery). Strona z 50 tysiącami sesji miesięcznie generuje zwykle kilkaset tysięcy zdarzeń, czyli w okolicach gigabajta danych na miesiąc. Darmowe 10 GB starcza więc na kilka lat historii.

Piaskownica ma jedną pułapkę: tabele i partycje wygasają po 60 dniach. Kto chce budować historię, musi albo podpiąć konto rozliczeniowe (darmowy poziom nadal obowiązuje, a rachunek przy takim ruchu zwykle wynosi zero), albo regularnie agregować dane do własnych tabel.

Koszty zapytań kontroluje się trzema nawykami. Po pierwsze, nie używaj SELECT *, bo BigQuery nalicza za odczytane kolumny. Po drugie, zawężaj zakres przez _TABLE_SUFFIX. Po trzecie, ustaw w projekcie limit przetworzonych bajtów na zapytanie, żeby jeden błąd nie zjadł miesięcznego terabajta.

Pierwsze zapytania: sesje, źródła, konwersje

Liczba sesji i użytkowników z ostatnich siedmiu dni:

SELECT
  COUNT(DISTINCT CONCAT(user_pseudo_id, CAST(
    (SELECT value.int_value FROM UNNEST(event_params)
     WHERE key = 'ga_session_id') AS STRING))) AS sesje,
  COUNT(DISTINCT user_pseudo_id) AS uzytkownicy
FROM `projekt.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY));

Źródła i media sesji, liczone z pola session_traffic_source_last_click:

SELECT
  session_traffic_source_last_click.manual_campaign.source AS zrodlo,
  session_traffic_source_last_click.manual_campaign.medium AS medium,
  COUNT(*) AS rozpoczete_sesje
FROM `projekt.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261025'
  AND event_name = 'session_start'
GROUP BY 1, 2
ORDER BY 3 DESC;

Konwersje według strony, na której nastąpiły:

SELECT
  (SELECT value.string_value FROM UNNEST(event_params)
   WHERE key = 'page_location') AS strona,
  COUNT(*) AS zakupy,
  SUM(ecommerce.purchase_revenue) AS przychod
FROM `projekt.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261025'
  AND event_name = 'purchase'
GROUP BY 1
ORDER BY 3 DESC;

Liczby nie zgodzą się co do sztuki z interfejsem: GA4 szacuje użytkowników algorytmem HyperLogLog, a w raportach stosuje modelowanie. Różnica rzędu kilku procent jest normalna. Wyniki najłatwiej pokazać w Looker Studio, podpinając BigQuery jako źródło; gotowe układy raportów znajdziesz w zestawieniu siedmiu wzorców dashboardów w Looker Studio. Warto też zestawić ruch z danymi z wyszukiwarki: Search Console ma osobny, równie darmowy eksport, opisany w tekście o masowym eksporcie Search Console do BigQuery.

Czego eksport nie naprawi

Eksport nie działa wstecz. Dane trafiają do BigQuery od dnia połączenia, więc historię sprzed tej daty trzeba wyciągnąć osobno, na przykład przez API GA4, i to już w zagregowanej formie.

Nie naprawi też braków w zbieraniu danych. Jeśli tag nie odpala na części stron albo zdarzenie ma źle nazwany parametr, w BigQuery zobaczysz dokładnie ten sam błąd, tylko bardziej szczegółowo. Nie dostaniesz również danych modelowanych: konwersji szacowanych przy odmowie zgody w Consent Mode, demografii z Google Signals ani gotowej atrybucji opartej na danych. Użytkownicy bez zgody pojawiają się w tabelach bez stałego identyfikatora, więc nie da się ich połączyć w ścieżki.

Wreszcie eksport nie zastąpi kompetencji. Surowe zdarzenia wymagają SQL i znajomości modelu danych GA4. Bez tego łatwo policzyć sesje dwa razy albo zgubić zakupy z parametrem zapisanym w innym typie pola.

Kiedy więc eksport nie ma sensu? Jeśli strona ma kilkaset wizyt miesięcznie, raporty standardowe nie próbkują, a nikt w zespole nie napisze zapytania SQL, połączenie przez długie miesiące będzie tylko zbierać dane. Nawet wtedy warto je jednak włączyć: kosztuje kwadrans, a historia zdarzeń zaczyna się budować od pierwszego dnia. Gdy za rok przyjdzie potrzeba analizy ścieżek albo porównania kohort, surowe dane już będą czekać w projekcie.

FAQ

Czy eksport GA4 do BigQuery jest darmowy?

Eksport dzienny jest bezpłatny po stronie GA4. Płacisz tylko za BigQuery, a przy małym i średnim ruchu mieścisz się w darmowym poziomie: 10 GB przechowywania i 1 TB zapytań miesięcznie. Płatny jest eksport strumieniowy (0,05 USD za GB).

Czy po połączeniu zobaczę w BigQuery dane historyczne?

Nie. Eksport zaczyna się od dnia konfiguracji. Starsze dane można pobrać tylko w formie zagregowanej przez Data API albo z raportów.

Czy da się korzystać z eksportu bez karty płatniczej?

Tak, w piaskownicy BigQuery. Ograniczenia to brak eksportu strumieniowego i wygasanie tabel po 60 dniach, dlatego do budowania historii lepiej podpiąć konto rozliczeniowe.

Dlaczego liczba użytkowników w BigQuery różni się od GA4?

Interfejs GA4 szacuje unikalnych użytkowników algorytmem HyperLogLog i korzysta z modelowania, a BigQuery liczy dokładnie surowe identyfikatory. Rozbieżność kilku procent jest typowa i nie oznacza błędu.

Ile zdarzeń dziennie można wyeksportować w darmowej wersji GA4?

Usługi standardowe mają dzienny limit miliona zdarzeń w eksporcie dziennym. Eksport strumieniowy nie ma limitu wolumenu, ale jest płatny.