ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Construction de la clé de session GA4

Pourquoi ga_session_id seul échoue comme identifiant de session, comment construire la clé composite correcte, et les cas limites qui produisent des sessions nulles.

Planté
ga4bigquerydata modelinganalytics

L’erreur la plus courante dans la sessionisation GA4 est d’utiliser ga_session_id seul comme identifiant de session. Ce champ est stocké dans le tableau event_params comme valeur entière, et représente le timestamp Unix (en secondes) du démarrage de la session. Le problème : plusieurs utilisateurs peuvent démarrer des sessions à la même seconde.

Avec un volume de trafic raisonnable, les collisions de timestamp sont garanties. Utiliser uniquement ga_session_id regroupe les événements de différents utilisateurs dans la même « session », corrompant chaque métrique en aval. L’attribution devient incorrecte lorsqu’une session contient des événements d’utilisateurs arrivés via différents canaux. La durée de session s’allonge. Les taux de conversion se faussent.

Le pattern correct

La correction est mécanique : concaténer user_pseudo_id avec ga_session_id pour créer une clé de session véritablement unique.

CONCAT(
user_pseudo_id,
'.',
CAST(
(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
AS STRING
)
) AS session_key

Cette session_key devient le fondement de toutes les fonctions de fenêtrage dans le modèle sessionisé. Chaque calcul à portée de session — timestamps, attribution, ordonnancement des événements — effectue une partition sur ce champ.

Le séparateur par point est une convention, pas une obligation. Certaines équipes utilisent des underscores ou des tirets. Ce qui compte, c’est que la concaténation produise une valeur unique pour tous les utilisateurs et sessions.

Le piège int_value

ga_session_id vit dans value.int_value, pas value.string_value. Cela perturbe les personnes qui extraient réflexivement les paramètres d’événement sous forme de chaînes. L’extraction depuis string_value retourne des nulls, et ces nulls se propagent en cascade dans la construction de votre clé de session, produisant soit des clés de session nulles (qui sont filtrées) soit des sessions où tous les événements à clé nulle fusionnent en une seule immense « session ».

-- INCORRECT : Retourne NULL
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
-- CORRECT : Retourne l'ID de session entier
(SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')

Castez toujours en STRING après l’extraction pour la concaténation.

Cas limites produisant des sessions nulles

Les événements peuvent arriver sans ga_session_id dans plusieurs scénarios :

Rejet du consentement. Lorsque les utilisateurs rejettent le consentement de tracking, ga_session_id et user_pseudo_id deviennent nuls. Ces événements ne portent aucune identité de session et doivent être filtrés de votre modèle sessionisé. Ils ne sont pas récupérables — il n’y a pas d’identifiant pour les regrouper.

Hits Measurement Protocol. Les événements côté serveur envoyés via le Measurement Protocol peuvent manquer de contexte de session si l’implémentation ne transmet pas session_id et client_id. C’est un écart d’implémentation, pas une limitation de GA4.

Filtrage des sous-propriétés. Les sous-propriétés GA4 peuvent filtrer les événements session_start tout en conservant les autres événements. L’ID de session se propage quand même aux événements non session_start, mais il est important de tester les cas limites dans votre configuration de propriété spécifique.

Filtrez ces événements dans votre modèle de base pour éviter que les clés de session nulles ne se propagent en aval :

WHERE (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') IS NOT NULL

Ce filtre appartient au modèle le plus en amont possible. Les clés de session nulles brisent toutes les fonctions de fenêtrage partitionnées par session_key, produisant des résultats sans signification plutôt que des erreurs.

Sessions multi-appareils

Le user_pseudo_id est spécifique à l’appareil. C’est un identifiant par cookie first-party lié au navigateur ou à l’instance d’application où il a été défini. La même personne naviguant sur son téléphone puis achetant sur son ordinateur portable crée deux pseudo IDs distincts et donc deux sessions distinctes.

Ces sessions ne peuvent pas être liées au niveau de la sessionisation. Les connecter nécessite une résolution d’identité — faire correspondre les identifiants d’appareils anonymes à une identité utilisateur connue lors des événements d’authentification. C’est un problème distinct de la sessionisation qui implique généralement un modèle de réconciliation utilisateur mappant les valeurs user_pseudo_id aux valeurs user_id.

Jusqu’à ce qu’un utilisateur s’authentifie sur les deux appareils, ses sessions restent séparées. C’est une limitation fondamentale des identifiants liés à l’appareil, pas un défaut de la construction de la clé de session.

Valider votre clé de session

Une requête de validation rapide confirme que votre clé de session fonctionne correctement :

SELECT
session_key,
COUNT(DISTINCT user_pseudo_id) AS distinct_users
FROM sessionized_events
GROUP BY session_key
HAVING COUNT(DISTINCT user_pseudo_id) > 1

Cela devrait retourner zéro ligne. Si des résultats apparaissent, votre clé de session permet à des événements de plusieurs utilisateurs de partager une session — probablement parce que vous utilisez ga_session_id seul ou que votre logique de concaténation contient un bug.

Une deuxième vérification confirme que les sessions ont des caractéristiques raisonnables :

SELECT
APPROX_QUANTILES(event_count, 100)[OFFSET(50)] AS median_events,
APPROX_QUANTILES(event_count, 100)[OFFSET(95)] AS p95_events,
APPROX_QUANTILES(duration_seconds, 100)[OFFSET(50)] AS median_duration,
APPROX_QUANTILES(duration_seconds, 100)[OFFSET(95)] AS p95_duration
FROM (
SELECT
session_key,
COUNT(*) AS event_count,
(MAX(event_timestamp) - MIN(event_timestamp)) / 1000000 AS duration_seconds
FROM sessionized_events
GROUP BY session_key
)

Des comptages d’événements ou des durées anormalement élevés suggèrent des collisions de clés de session ou des filtres manquants. Une session avec 10 000 événements sur 24 heures est presque certainement plusieurs sessions fusionnées.

Relation avec la sessionisation personnalisée

La clé composite décrite ici fonctionne avec la définition de session intégrée de GA4 (délai d’inactivité de 30 minutes). Si vous avez besoin de limites de session personnalisées — différents délais d’expiration, séparations basées sur des campagnes — vous construirez vos propres identifiants de session avec le pattern LAG + SUM cumulatif. Dans ce cas, ga_session_id devient simplement un point de référence, et votre clé de session personnalisée remplace la clé composite pour toute l’analyse en aval.

Pour la plupart des travaux d’analyse GA4, la clé composite user_pseudo_id.ga_session_id est suffisante. La sessionisation personnalisée n’est nécessaire que lorsque la définition de session de GA4 ne correspond pas aux besoins métier.