GA4 + BigQuery: Export, schéma, requêtes SQL et cas d'usage
Les coûts BigQuery mentionnés correspondent aux tarifs Google Cloud Platform en vigueur en mai 2026 et peuvent évoluer. Vérifiez les tarifs actuels sur cloud.google.com/bigquery/pricing avant toute décision.
Activer l'export, comprendre le schéma event_params et UNNEST, requêtes SQL prêtes à l'emploi, coûts réels et connexion Looker Studio — guide technique de référence.
GA4 BigQuery · export GA4 BigQuery · GA4 BigQuery schéma · requêtes SQL GA4 BigQuery · GA4 BigQuery cost · Looker Studio BigQuery
L'export GA4 vers BigQuery copie quotidiennement tous vos événements GA4 bruts dans un entrepôt de données cloud. Vous accédez alors à 100 % de vos données — sans sampling, sans limite de rétention — et vous pouvez les interroger en SQL pour des analyses impossibles dans l'interface GA4.
Ce que ça débloque : croisement avec vos données CRM et coûts publicitaires, analyses de rétention et cohortes illimitées, calcul de métriques personnalisées (LTV, ROAS réel cross-canal, entonnoirs sur plusieurs mois), et dashboards Looker Studio non samplés.
Limite importante : l'export standard GA4 est plafonné à 1 million d'événements par jour. GA4 360 supprime cette limite. Pour la plupart des sites, ce seuil est largement suffisant — mais si vous gérez un site à très fort volume, vérifiez-le avant de vous engager.
Pourquoi GA4 + BigQuery — et quand c'est vraiment nécessaire
L'interface GA4 standard couvre 80 % des besoins analytics d'un site web. Mais il y a 4 situations où elle atteint ses limites — et où l'export GA4 BigQuery devient indispensable.
| Situation | Limite GA4 standard | Ce que BigQuery résout |
|---|---|---|
| Grands volumes de données | Les Explorations GA4 échantillonnent dès que les seuils de quotas sont dépassés | Accès aux 100 % des événements bruts, non samplés, via SQL |
| Rétention longue durée | Maximum 14 mois de données dans l'interface GA4 | Rétention illimitée dans BigQuery |
| Croisement de données | GA4 ne peut pas être joint à votre CRM, vos données de coût Meta, vos remboursements | JOIN SQL entre tables GA4 et CRM, données de coût, bases produits |
| Métriques personnalisées complexes | LTV, ROAS cross-canal, taux de réachat, cohortes avancées — impossibles dans l'interface | N'importe quelle métrique calculable en SQL — liberté totale d'analyse |
Vos Explorations GA4 sont samplées et vous perdez la fiabilité de vos analyses ? L'intégration BigQuery résout ce problème.
Décrivez-nous votre situation →GA4 BigQuery cost — coût réel de l'export en 2026
La réponse courte : l'export GA4 vers BigQuery est gratuit à l'activation. Les coûts potentiels viennent de l'usage de la plateforme BigQuery elle-même.
| Composant | Coût | Détail |
|---|---|---|
| Activation du lien GA4 → BigQuery | ✅ Gratuit | Aucun coût pour créer le lien et commencer l'export |
| Limite d'événements / jour | ⚠️ 1M événements/jour (standard) Illimité (GA4 360) |
L'export standard est plafonné à 1 million d'événements par jour. La plupart des sites sont en dessous — vérifiez si vous gérez un site à très fort volume |
| Stockage BigQuery | ✅ Gratuit jusqu'à 10 Go/mois Puis ~0,02 $/Go/mois |
Un site moyen (500K sessions/mois) génère ~2–5 Go de données GA4/mois — souvent dans la limite gratuite |
| Requêtes SQL (traitement) | ✅ Gratuit jusqu'à 1 To/mois Puis ~5 $/To traité |
Une requête bien optimisée sur 30 jours de données traite généralement 0,5–5 Go — très loin du seuil gratuit |
| Export streaming (temps réel) | ⚠️ ~0,05 $/Go de données | L'export streaming génère des coûts. Pour la plupart des cas, l'export quotidien suffit |
- Utilisez les tables partitionnées par date (_TABLE_SUFFIX) — filtrez toujours sur la plage de dates exacte nécessaire
- Sélectionnez uniquement les colonnes nécessaires (pas de SELECT *) — BigQuery facture le volume de données scanné
- Créez des vues matérialisées ou des tables agrégées via dbt ou des requêtes planifiées — évitez de recalculer les mêmes métriques à chaque requête
- Configurez des alertes de budget GCP pour être prévenu si les coûts dépassent un seuil défini
- Lancez des dry runs avant les grandes requêtes — BigQuery vous indique le volume de données qui sera scanné (et donc le coût) sans exécuter la requête
GA4 BigQuery integration — activer l'export pas à pas
-
1Créer un projet Google Cloud Platform
Sur
console.cloud.google.com, créez un projet GCP ou utilisez un projet existant. Activez la facturation (obligatoire même pour l'usage dans les limites gratuites — une carte bancaire est requise). Dans APIs & Services → activez l'API BigQuery. -
2Créer le lien BigQuery dans GA4
GA4 → Admin → Liens de produits → BigQuery → Lier → Sélectionnez votre projet GCP. Choisissez la région (EU recommandée pour la conformité RGPD), la fréquence d'export, et les événements à exclure éventuellement.
-
3Vérifier le dataset dans BigQuery
Une fois l'export activé, dans BigQuery → Explorer → votre projet → un dataset nommé
analytics_XXXXXXXXXapparaît. Les tablesevents_YYYYMMDDse peuplent en général en début d'après-midi (selon le fuseau horaire de votre propriété GA4) — pas à minuit. Il n'y a pas de backfill automatique — les données antérieures à l'activation ne sont pas exportées. -
4Vérifier les permissions
Le compte de service Google Analytics doit avoir le rôle BigQuery Data Editor sur votre projet GCP. GA4 configure cela automatiquement lors de la création du lien — vérifiez dans GCP → IAM & Admin si des problèmes surviennent.
Schéma des données GA4 BigQuery — comprendre event_params et UNNEST
Structure des tables
L'export BigQuery GA4 crée deux types de tables dans votre dataset :
events_YYYYMMDD— une table par jour (ex:events_20260508), données finales. C'est votre source de vérité pour le reporting.events_intraday_YYYYMMDD— données en cours de journée, mises à jour toutes les 15–30 minutes (nécessite l'export streaming). Attention : écart de 0,5 à 2 % entre intraday et les données quotidiennes finales — ne pas utiliser pour le reporting final ni l'attribution.
Chaque ligne = un événement. Colonnes principales :
| Colonne | Type | Contenu |
|---|---|---|
event_date | STRING | Date de l'événement au format YYYYMMDD |
event_timestamp | INTEGER | Timestamp en microsecondes (÷ 1 000 000 pour les secondes) |
event_name | STRING | Nom de l'événement (page_view, purchase, scroll…) |
user_pseudo_id | STRING | Identifiant pseudo-anonyme de l'utilisateur |
user_id | STRING | User ID si configuré dans GA4 — sinon NULL |
event_params | ARRAY<STRUCT> | Paramètres de l'événement — nécessite UNNEST |
user_properties | ARRAY<STRUCT> | Propriétés utilisateur — nécessite UNNEST |
device.category | STRING | desktop / mobile / tablet |
geo.country | STRING | Pays de l'utilisateur |
traffic_source.medium | STRING | Medium de la première session |
Comprendre UNNEST — la clé de tout
La colonne event_params contient un tableau (ARRAY) de paires clé-valeur pour chaque événement. Pour accéder à une valeur spécifique, vous devez utiliser UNNEST :
-- Récupérer la page_location de tous les page_view
SELECT
event_date,
event_name,
user_pseudo_id,
(SELECT value.string_value
FROM UNNEST(event_params)
WHERE key = 'page_location') AS page_location
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE event_name = 'page_view'
AND _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
LIMIT 1000;
Le pattern (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'NOM_PARAM') est la structure de base de 90 % des requêtes GA4 BigQuery. Pour les paramètres numériques, remplacez string_value par int_value ou float_value.
ga_session_id dans BigQuery GA4
Le ga_session_id BigQuery GA4 est stocké dans event_params sous la clé ga_session_id :
(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS session_id
Combiné avec user_pseudo_id, il crée un identifiant de session unique : CONCAT(user_pseudo_id, '.', CAST(session_id AS STRING)).
GA4 BigQuery queries — requêtes SQL prêtes à l'emploi
Remplacez votre_projet.analytics_XXXXXXXXX par vos identifiants réels.
Requête 1 — Sessions par canal (source / medium)
SELECT
traffic_source.medium AS medium,
traffic_source.source AS source,
COUNT(DISTINCT CONCAT(user_pseudo_id, '.',
CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)
)) AS sessions
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
AND event_name = 'session_start'
GROUP BY medium, source
ORDER BY sessions DESC
LIMIT 50;
Requête 2 — Revenus e-commerce avec déduplication des transactions
SELECT
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'transaction_id') AS transaction_id,
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'currency') AS currency,
(SELECT value.double_value FROM UNNEST(event_params) WHERE key = 'value') AS revenue,
event_date,
device.category AS device,
traffic_source.medium AS medium
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
AND event_name = 'purchase'
-- Déduplication élégante avec QUALIFY — une seule ligne par transaction_id
QUALIFY ROW_NUMBER() OVER (
PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'transaction_id')
ORDER BY event_timestamp ASC
) = 1
ORDER BY event_date DESC;
Requête 3 — Taux d'engagement (bounce rate GA4 BigQuery)
WITH sessions AS (
SELECT
CONCAT(user_pseudo_id, '.',
CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)
) AS session_id,
MAX(CASE WHEN event_name = 'user_engagement' THEN 1 ELSE 0 END) AS is_engaged,
MAX(CASE WHEN (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'engagement_time_msec') > 10000
THEN 1 ELSE 0 END) AS long_engagement,
COUNT(DISTINCT (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location')) AS pages_viewed
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
GROUP BY session_id
)
SELECT
COUNT(*) AS total_sessions,
SUM(CASE WHEN is_engaged = 1 OR long_engagement = 1 OR pages_viewed >= 2 THEN 1 ELSE 0 END) AS engaged_sessions,
ROUND(100 * SUM(CASE WHEN is_engaged = 1 OR long_engagement = 1 OR pages_viewed >= 2 THEN 1 ELSE 0 END) / COUNT(*), 2) AS engagement_rate,
ROUND(100 - 100 * SUM(CASE WHEN is_engaged = 1 OR long_engagement = 1 OR pages_viewed >= 2 THEN 1 ELSE 0 END) / COUNT(*), 2) AS bounce_rate
FROM sessions;
Requête 4 — Default channel grouping GA4 BigQuery
SELECT
CASE
WHEN traffic_source.medium = 'organic' AND traffic_source.source IN ('google','bing','yahoo','baidu','duckduckgo') THEN 'Organic Search'
WHEN traffic_source.medium IN ('cpc','ppc','paidsearch') THEN 'Paid Search'
WHEN traffic_source.medium = 'email' THEN 'Email'
WHEN traffic_source.medium IN ('social','social-network','social-media','sm') THEN 'Organic Social'
WHEN traffic_source.medium = 'referral' THEN 'Referral'
WHEN traffic_source.medium = '(none)' AND traffic_source.source = '(direct)' THEN 'Direct'
WHEN REGEXP_CONTAINS(traffic_source.medium, r'^(display|cpm|banner)$') THEN 'Display'
ELSE 'Unassigned'
END AS default_channel_grouping,
COUNT(DISTINCT user_pseudo_id) AS users,
COUNT(DISTINCT CONCAT(user_pseudo_id, '.',
CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)
)) AS sessions
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
AND event_name = 'session_start'
GROUP BY 1
ORDER BY sessions DESC;
Requête 5 — Landing pages avec taux de conversion
WITH session_data AS (
SELECT
CONCAT(user_pseudo_id, '.',
CAST((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS STRING)
) AS session_id,
MIN(CASE WHEN event_name = 'session_start'
THEN (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location')
END) AS landing_page,
MAX(CASE WHEN event_name = 'purchase' THEN 1 ELSE 0 END) AS converted
FROM `votre_projet.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260401' AND '20260508'
GROUP BY session_id
)
SELECT
REGEXP_REPLACE(landing_page, r'\?.*$', '') AS landing_page_clean,
COUNT(*) AS sessions,
SUM(converted) AS purchases,
ROUND(100 * SUM(converted) / COUNT(*), 2) AS purchase_conversion_rate
FROM session_data
WHERE landing_page IS NOT NULL
GROUP BY landing_page_clean
HAVING sessions >= 50
ORDER BY sessions DESC
LIMIT 30;
Cas d'usage business — ce que GA4 + BigQuery permet vraiment
Vous reconnaissez un ou plusieurs de ces besoins ? L'intégration GA4 + BigQuery est notre service le plus avancé.
Décrivez-nous votre projet →GA4 BigQuery Looker Studio — connexion et dashboards
| Looker Studio → GA4 direct | Looker Studio → BigQuery | |
|---|---|---|
| Sampling | ⚠️ Possible sur grands volumes | ✅ Aucun — données brutes complètes |
| Données multi-sources | ❌ GA4 uniquement par connecteur | ✅ GA4 + CRM + Ads + tout ce que BigQuery contient |
| Métriques calculées | Limitées aux formules Looker Studio | ✅ SQL complet |
| Rétention | Limitée par GA4 (14 mois) | ✅ Illimitée |
Dans Looker Studio → Créer → Source de données → BigQuery → sélectionnez votre projet, dataset et table. Pour les rapports de production, utilisez une vue BigQuery ou une table matérialisée plutôt que la table brute — les requêtes seront plus rapides et moins coûteuses. Pour les équipes qui ne maîtrisent pas SQL, des outils comme dbt permettent de créer et maintenir ces vues de façon structurée.
GA4 seul vs GA4 + BigQuery — quand basculer
Décrivez-nous votre situation.
CMS utilisé, outils Google en place, symptômes observés — plus vous êtes précis, plus notre retour sera concret. Réponse sous 24h.
Parlez-nous de votre projet →Réponse sous 24h · Sans engagement · Devis sur mesure
Questions fréquentes
event_params) sont stockés dans BigQuery sous forme d'ARRAY de STRUCT — un tableau de paires clé-valeur. Pour accéder à la valeur d'un paramètre spécifique (ex: page_location, session_id, transaction_id), vous devez dérouler ce tableau avec UNNEST et filtrer sur la clé souhaitée. C'est le pattern de base de la grande majorité des requêtes GA4 BigQuery.events_YYYYMMDD chaque jour — données finales, disponibles en général en début d'après-midi selon le timezone de votre propriété GA4. Gratuit, suffisant pour 95 % des cas, source de vérité pour le reporting et l'attribution. L'export streaming crée des tables events_intraday_YYYYMMDD mises à jour toutes les 15–30 minutes — génère des coûts additionnels et présente un écart de 0,5–2 % avec les données finales. Ne pas utiliser les tables intraday pour le reporting final.