Learner Engagement Time
Also known as: Learning Engagement Time, Active Learning Time, Learner Active Time, Time Engaged, Learning Activity Time, Engaged Learning Duration, Time on Learning Content
Measures the total active time learners spend interacting with eligible learning content and activities during a defined reporting window. It excludes background, idle, duplicate, invalid, and non-learning activity so that the result represents attributable learning engagement rather than elapsed session duration.
Business Use Case
The Chief Product Officer reviews monthly engagement time by course, lesson, content format, and learner cohort to identify high-enrollment content with declining active time. Product and instructional design teams then investigate telemetry-confirmed drop-off points, revise or replace low-engagement activities, and compare post-release engagement time and completion-rate changes against the pre-release baseline.
Business Criticality
High
Journey / Navigation Area
Engagement
Owning Function
Learning Product Management
Scope
User
Formula
SUM_over_learners(DURATION_SECONDS(UNION(CLIP(eligible_active_intervals, window_start, window_end))))Calculation Notes
1️⃣ Build active intervals from engagement events (start, pause, resume, etc.). 2️⃣ Clip intervals to reporting-window boundaries. 3️⃣ Merge overlapping or adjacent intervals for the same learner. 4️⃣ Count the union once to avoid time duplication across tabs/devices. 5️⃣ Prefer measured foreground-active duration; infer time only between eligible events ≤60 seconds apart. 6️⃣ Pause accumulation when the app is hidden, device is locked, or media is paused/buffering. 7️⃣ For offline activity, use validated client event time after sync under late-arriving-data policy.
Technical Details
Events
| Platform | Event |
|---|---|
| Google Analytics 4 | user_engagement |
| Adobe | user_engagement |
Data Mappings
W3 Data Layer
{
"digitalData": {
"event": [
{
"eventInfo": {
"eventName": "user_engagement",
"eventType": "engagement",
"timeStamp": "2025-01-15T10:10:00.000Z",
"eventAction": "user_engagement"
},
"attributes": {
"app_id": "learning-web",
"lab_id": "",
"event_id": "eng-7f47d852-c0c2-4b7e-9098-546da02d57aa",
"media_id": "",
"platform": "learning_management_system",
"course_id": "course-1001",
"lesson_id": "lesson-4001",
"module_id": "module-3001",
"content_id": "content-6001",
"learner_id": "learner-12345",
"session_id": "1736935200",
"activity_id": "activity-5001",
"app_version": "5.4.1",
"course_name": "Example Course",
"device_type": "desktop",
"anonymous_id": "anon-67890",
"content_type": "interactive_lesson",
"activity_type": "lesson",
"assessment_id": "",
"content_title": "Example Learning Activity",
"engagement_id": "engagement-98765",
"enrollment_id": "enrollment-24680",
"event_version": "1.0",
"page_location": "https://learning.example.com/courses/course-1001/lessons/lesson-4001",
"page_referrer": "https://learning.example.com/courses/course-1001",
"course_version": "3.2",
"idle_time_msec": 90000,
"event_timestamp": "2025-01-15T10:10:00.000Z",
"active_time_msec": 420000,
"content_language": "en-US",
"content_provider": "internal",
"delivery_channel": "web",
"interaction_type": "content_interaction",
"learning_path_id": "path-2001",
"completion_status": "in_progress",
"elapsed_time_msec": 600000,
"invalid_time_msec": 5000,
"identity_namespace": "LMSID",
"duplicate_time_msec": 10000,
"engagement_end_time": "2025-01-15T10:10:00.000Z",
"identity_auth_state": "authenticated",
"reporting_window_id": "2025-01-15",
"attribution_eligible": true,
"background_time_msec": 30000,
"engagement_time_msec": 420000,
"reporting_window_end": "2025-01-15T23:59:59.999Z",
"engagement_start_time": "2025-01-15T10:00:00.000Z",
"non_learning_time_msec": 45000,
"reporting_window_start": "2025-01-15T00:00:00.000Z"
}
}
]
}
}GA4 Data Layer
{
"event": "user_engagement",
"app_id": "learning-web",
"lab_id": "",
"event_id": "eng-7f47d852-c0c2-4b7e-9098-546da02d57aa",
"media_id": "",
"platform": "learning_management_system",
"course_id": "course-1001",
"lesson_id": "lesson-4001",
"module_id": "module-3001",
"content_id": "content-6001",
"learner_id": "learner-12345",
"activity_id": "activity-5001",
"app_version": "5.4.1",
"course_name": "Example Course",
"device_type": "desktop",
"anonymous_id": "anon-67890",
"content_type": "interactive_lesson",
"activity_type": "lesson",
"assessment_id": "",
"content_title": "Example Learning Activity",
"engagement_id": "engagement-98765",
"enrollment_id": "enrollment-24680",
"event_version": "1.0",
"ga_session_id": "1736935200",
"page_location": "https://learning.example.com/courses/course-1001/lessons/lesson-4001",
"page_referrer": "https://learning.example.com/courses/course-1001",
"course_version": "3.2",
"idle_time_msec": 90000,
"event_timestamp": "2025-01-15T10:10:00.000Z",
"active_time_msec": 420000,
"content_language": "en-US",
"content_provider": "internal",
"delivery_channel": "web",
"interaction_type": "content_interaction",
"learning_path_id": "path-2001",
"completion_status": "in_progress",
"elapsed_time_msec": 600000,
"invalid_time_msec": 5000,
"identity_namespace": "LMSID",
"duplicate_time_msec": 10000,
"engagement_end_time": "2025-01-15T10:10:00.000Z",
"identity_auth_state": "authenticated",
"reporting_window_id": "2025-01-15",
"attribution_eligible": true,
"background_time_msec": 30000,
"engagement_time_msec": 420000,
"reporting_window_end": "2025-01-15T23:59:59.999Z",
"engagement_start_time": "2025-01-15T10:00:00.000Z",
"non_learning_time_msec": 45000,
"reporting_window_start": "2025-01-15T00:00:00.000Z"
}Adobe Client Data Layer
{
"data": {
"learnerEngagement": {
"app_id": "learning-web",
"lab_id": "",
"event_id": "eng-7f47d852-c0c2-4b7e-9098-546da02d57aa",
"media_id": "",
"platform": "learning_management_system",
"course_id": "course-1001",
"lesson_id": "lesson-4001",
"module_id": "module-3001",
"content_id": "content-6001",
"learner_id": "learner-12345",
"session_id": "1736935200",
"activity_id": "activity-5001",
"app_version": "5.4.1",
"course_name": "Example Course",
"device_type": "desktop",
"anonymous_id": "anon-67890",
"content_type": "interactive_lesson",
"activity_type": "lesson",
"assessment_id": "",
"content_title": "Example Learning Activity",
"engagement_id": "engagement-98765",
"enrollment_id": "enrollment-24680",
"event_version": "1.0",
"page_location": "https://learning.example.com/courses/course-1001/lessons/lesson-4001",
"page_referrer": "https://learning.example.com/courses/course-1001",
"course_version": "3.2",
"idle_time_msec": 90000,
"event_timestamp": "2025-01-15T10:10:00.000Z",
"active_time_msec": 420000,
"content_language": "en-US",
"content_provider": "internal",
"delivery_channel": "web",
"interaction_type": "content_interaction",
"learning_path_id": "path-2001",
"completion_status": "in_progress",
"elapsed_time_msec": 600000,
"invalid_time_msec": 5000,
"identity_namespace": "LMSID",
"duplicate_time_msec": 10000,
"engagement_end_time": "2025-01-15T10:10:00.000Z",
"identity_auth_state": "authenticated",
"reporting_window_id": "2025-01-15",
"attribution_eligible": true,
"background_time_msec": 30000,
"engagement_time_msec": 420000,
"reporting_window_end": "2025-01-15T23:59:59.999Z",
"engagement_start_time": "2025-01-15T10:00:00.000Z",
"non_learning_time_msec": 45000,
"reporting_window_start": "2025-01-15T00:00:00.000Z"
}
},
"event": "user_engagement"
}XDM Mapping
{
"web": {
"webReferrer": {
"URL": "https://learning.example.com/courses/course-1001"
},
"webPageDetails": {
"URL": "https://learning.example.com/courses/course-1001/lessons/lesson-4001",
"name": "Example Learning Activity"
}
},
"device": {
"type": "desktop"
},
"eventID": "eng-7f47d852-c0c2-4b7e-9098-546da02d57aa",
"_learning": {
"learnerEngagement": {
"app_id": "learning-web",
"lab_id": "",
"event_id": "eng-7f47d852-c0c2-4b7e-9098-546da02d57aa",
"media_id": "",
"platform": "learning_management_system",
"course_id": "course-1001",
"lesson_id": "lesson-4001",
"module_id": "module-3001",
"content_id": "content-6001",
"learner_id": "learner-12345",
"session_id": "1736935200",
"activity_id": "activity-5001",
"app_version": "5.4.1",
"course_name": "Example Course",
"device_type": "desktop",
"anonymous_id": "anon-67890",
"content_type": "interactive_lesson",
"activity_type": "lesson",
"assessment_id": "",
"content_title": "Example Learning Activity",
"engagement_id": "engagement-98765",
"enrollment_id": "enrollment-24680",
"event_version": "1.0",
"page_location": "https://learning.example.com/courses/course-1001/lessons/lesson-4001",
"page_referrer": "https://learning.example.com/courses/course-1001",
"course_version": "3.2",
"idle_time_msec": 90000,
"event_timestamp": "2025-01-15T10:10:00.000Z",
"active_time_msec": 420000,
"content_language": "en-US",
"content_provider": "internal",
"delivery_channel": "web",
"interaction_type": "content_interaction",
"learning_path_id": "path-2001",
"completion_status": "in_progress",
"elapsed_time_msec": 600000,
"invalid_time_msec": 5000,
"identity_namespace": "LMSID",
"duplicate_time_msec": 10000,
"engagement_end_time": "2025-01-15T10:10:00.000Z",
"identity_auth_state": "authenticated",
"reporting_window_id": "2025-01-15",
"attribution_eligible": true,
"background_time_msec": 30000,
"engagement_time_msec": 420000,
"reporting_window_end": "2025-01-15T23:59:59.999Z",
"engagement_start_time": "2025-01-15T10:00:00.000Z",
"non_learning_time_msec": 45000,
"reporting_window_start": "2025-01-15T00:00:00.000Z"
}
},
"eventType": "user_engagement",
"timestamp": "2025-01-15T10:10:00.000Z",
"producedBy": "system",
"application": {
"id": "learning-web",
"version": "5.4.1"
},
"environment": {
"type": "browser"
},
"identityMap": {
"ECID": [
{
"id": "anon-67890",
"primary": false,
"authenticatedState": "ambiguous"
}
],
"LMSID": [
{
"id": "learner-12345",
"primary": true,
"authenticatedState": "authenticated"
}
]
}
}SQL Queries
Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
WITH source_events AS (
SELECT
e.*,
(
SELECT AS STRUCT
MAX(IF(key = 'event_id', param_value, NULL)) AS event_id,
MAX(IF(key = 'event_version', param_value, NULL)) AS event_version,
MAX(IF(key = 'event_timestamp', param_value, NULL)) AS event_timestamp_value,
MAX(IF(key = 'reporting_window_id', param_value, NULL)) AS reporting_window_id,
MAX(IF(key = 'reporting_window_start', param_value, NULL)) AS reporting_window_start,
MAX(IF(key = 'reporting_window_end', param_value, NULL)) AS reporting_window_end,
MAX(IF(key = 'learner_id', param_value, NULL)) AS learner_id,
MAX(IF(key = 'anonymous_id', param_value, NULL)) AS anonymous_id,
MAX(IF(key = 'identity_namespace', param_value, NULL)) AS identity_namespace,
MAX(IF(key = 'identity_auth_state', param_value, NULL)) AS identity_auth_state,
MAX(IF(key IN ('ga_session_id', 'session_id'), param_value, NULL)) AS session_id,
MAX(IF(key = 'engagement_id', param_value, NULL)) AS engagement_id,
MAX(IF(key = 'enrollment_id', param_value, NULL)) AS enrollment_id,
MAX(IF(key = 'course_id', param_value, NULL)) AS course_id,
MAX(IF(key = 'course_name', param_value, NULL)) AS course_name,
MAX(IF(key = 'course_version', param_value, NULL)) AS course_version,
MAX(IF(key = 'learning_path_id', param_value, NULL)) AS learning_path_id,
MAX(IF(key = 'module_id', param_value, NULL)) AS module_id,
MAX(IF(key = 'lesson_id', param_value, NULL)) AS lesson_id,
MAX(IF(key = 'activity_id', param_value, NULL)) AS activity_id,
MAX(IF(key = 'activity_type', param_value, NULL)) AS activity_type,
MAX(IF(key = 'content_id', param_value, NULL)) AS content_id,
MAX(IF(key = 'content_type', param_value, NULL)) AS content_type,
MAX(IF(key = 'content_title', param_value, NULL)) AS content_title,
MAX(IF(key = 'content_provider', param_value, NULL)) AS content_provider,
MAX(IF(key = 'content_language', param_value, NULL)) AS content_language,
MAX(IF(key = 'delivery_channel', param_value, NULL)) AS delivery_channel,
MAX(IF(key = 'platform', param_value, NULL)) AS platform,
MAX(IF(key = 'device_type', param_value, NULL)) AS device_type,
MAX(IF(key = 'app_id', param_value, NULL)) AS app_id,
MAX(IF(key = 'app_version', param_value, NULL)) AS app_version,
MAX(IF(key = 'page_location', param_value, NULL)) AS page_location,
MAX(IF(key = 'page_referrer', param_value, NULL)) AS page_referrer,
MAX(IF(key = 'media_id', param_value, NULL)) AS media_id,
MAX(IF(key = 'assessment_id', param_value, NULL)) AS assessment_id,
MAX(IF(key = 'lab_id', param_value, NULL)) AS lab_id,
MAX(IF(key = 'interaction_type', param_value, NULL)) AS interaction_type,
MAX(IF(key = 'engagement_start_time', param_value, NULL)) AS engagement_start_time,
MAX(IF(key = 'engagement_end_time', param_value, NULL)) AS engagement_end_time,
MAX(IF(key = 'active_time_msec', param_value, NULL)) AS active_time_msec,
MAX(IF(key = 'idle_time_msec', param_value, NULL)) AS idle_time_msec,
MAX(IF(key = 'background_time_msec', param_value, NULL)) AS background_time_msec,
MAX(IF(key = 'duplicate_time_msec', param_value, NULL)) AS duplicate_time_msec,
MAX(IF(key = 'invalid_time_msec', param_value, NULL)) AS invalid_time_msec,
MAX(IF(key = 'non_learning_time_msec', param_value, NULL)) AS non_learning_time_msec,
MAX(IF(key = 'elapsed_time_msec', param_value, NULL)) AS elapsed_time_msec,
MAX(IF(key = 'completion_status', param_value, NULL)) AS completion_status,
MAX(IF(key = 'attribution_eligible', param_value, NULL)) AS attribution_eligible,
MAX(IF(key = 'engagement_time_msec', param_value, NULL)) AS reported_engagement_time_msec
FROM (
SELECT
ep.key,
COALESCE(
ep.value.string_value,
CAST(ep.value.int_value AS STRING),
CAST(ep.value.double_value AS STRING),
CAST(ep.value.float_value AS STRING)
) AS param_value
FROM UNNEST(e.event_params) AS ep
)
) AS p
FROM `your-project.analytics_123456789.events_*` AS e
WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', @start_date)
AND FORMAT_DATE('%Y%m%d', @end_date)
AND e.event_name = 'user_engagement'
),
normalized AS (
SELECT
p.event_id,
p.event_version,
COALESCE(SAFE_CAST(p.event_timestamp_value AS TIMESTAMP), TIMESTAMP_MICROS(event_timestamp)) AS event_timestamp,
COALESCE(p.reporting_window_id, event_date) AS reporting_window_id,
SAFE_CAST(p.reporting_window_start AS TIMESTAMP) AS reporting_window_start,
SAFE_CAST(p.reporting_window_end AS TIMESTAMP) AS reporting_window_end,
COALESCE(NULLIF(p.learner_id, ''), user_id) AS learner_id,
COALESCE(NULLIF(p.anonymous_id, ''), user_pseudo_id) AS anonymous_id,
p.identity_namespace,
p.identity_auth_state,
p.session_id,
p.engagement_id,
p.enrollment_id,
p.course_id,
p.course_name,
p.course_version,
p.learning_path_id,
p.module_id,
p.lesson_id,
p.activity_id,
p.activity_type,
p.content_id,
p.content_type,
p.content_title,
p.content_provider,
p.content_language,
p.delivery_channel,
p.platform,
COALESCE(NULLIF(p.device_type, ''), device.category) AS device_type,
COALESCE(NULLIF(p.app_id, ''), app_info.id) AS app_id,
COALESCE(NULLIF(p.app_version, ''), app_info.version) AS app_version,
p.page_location,
p.page_referrer,
NULLIF(p.media_id, '') AS media_id,
NULLIF(p.assessment_id, '') AS assessment_id,
NULLIF(p.lab_id, '') AS lab_id,
p.interaction_type,
SAFE_CAST(p.engagement_start_time AS TIMESTAMP) AS engagement_start_time,
SAFE_CAST(p.engagement_end_time AS TIMESTAMP) AS engagement_end_time,
SAFE_CAST(p.active_time_msec AS INT64) AS active_time_msec,
SAFE_CAST(p.idle_time_msec AS INT64) AS idle_time_msec,
SAFE_CAST(p.background_time_msec AS INT64) AS background_time_msec,
SAFE_CAST(p.duplicate_time_msec AS INT64) AS duplicate_time_msec,
SAFE_CAST(p.invalid_time_msec AS INT64) AS invalid_time_msec,
SAFE_CAST(p.non_learning_time_msec AS INT64) AS non_learning_time_msec,
SAFE_CAST(p.elapsed_time_msec AS INT64) AS elapsed_time_msec,
p.completion_status,
COALESCE(SAFE_CAST(p.attribution_eligible AS BOOL), FALSE) AS attribution_eligible,
SAFE_CAST(p.reported_engagement_time_msec AS INT64) AS reported_engagement_time_msec,
event_bundle_sequence_id,
event_server_timestamp_offset
FROM source_events
),
deduplicated AS (
SELECT * EXCEPT(event_bundle_sequence_id, event_server_timestamp_offset)
FROM normalized
QUALIFY ROW_NUMBER() OVER (
PARTITION BY COALESCE(
NULLIF(event_id, ''),
CONCAT(
COALESCE(NULLIF(engagement_id, ''), 'unknown'), '|',
COALESCE(NULLIF(learner_id, ''), NULLIF(anonymous_id, ''), 'unknown'), '|',
CAST(event_timestamp AS STRING)
)
)
ORDER BY event_server_timestamp_offset DESC, event_bundle_sequence_id DESC
) = 1
),
measured AS (
SELECT
*,
COALESCE(
reported_engagement_time_msec,
active_time_msec,
GREATEST(
COALESCE(elapsed_time_msec, 0)
- COALESCE(idle_time_msec, 0)
- COALESCE(background_time_msec, 0)
- COALESCE(duplicate_time_msec, 0)
- COALESCE(invalid_time_msec, 0)
- COALESCE(non_learning_time_msec, 0),
0
)
) AS candidate_engagement_time_msec
FROM deduplicated
)
SELECT
event_id,
event_version,
event_timestamp,
reporting_window_id,
reporting_window_start,
reporting_window_end,
learner_id,
anonymous_id,
identity_namespace,
identity_auth_state,
session_id,
engagement_id,
enrollment_id,
course_id,
course_name,
course_version,
learning_path_id,
module_id,
lesson_id,
activity_id,
activity_type,
content_id,
content_type,
content_title,
content_provider,
content_language,
delivery_channel,
platform,
device_type,
app_id,
app_version,
page_location,
page_referrer,
media_id,
assessment_id,
lab_id,
interaction_type,
engagement_start_time,
engagement_end_time,
active_time_msec,
idle_time_msec,
background_time_msec,
duplicate_time_msec,
invalid_time_msec,
non_learning_time_msec,
elapsed_time_msec,
completion_status,
attribution_eligible,
CASE
WHEN attribution_eligible THEN GREATEST(
LEAST(
candidate_engagement_time_msec,
COALESCE(elapsed_time_msec, candidate_engagement_time_msec)
),
0
)
ELSE 0
END AS engagement_time_msec,
SAFE_DIVIDE(
CASE WHEN attribution_eligible THEN GREATEST(
LEAST(candidate_engagement_time_msec, COALESCE(elapsed_time_msec, candidate_engagement_time_msec)), 0
) ELSE 0 END,
1000.0
) AS engagement_time_seconds,
SAFE_DIVIDE(
CASE WHEN attribution_eligible THEN GREATEST(
LEAST(candidate_engagement_time_msec, COALESCE(elapsed_time_msec, candidate_engagement_time_msec)), 0
) ELSE 0 END,
60000.0
) AS engagement_time_minutes
FROM measured;Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
WITH source_events AS (
SELECT
e.eventType,
e.eventID AS xdm_event_id,
e.timestamp AS xdm_timestamp,
e._learning.learnerEngagement AS le
FROM learner_engagement_events AS e
WHERE e.timestamp >= CAST('${START_TIMESTAMP}' AS TIMESTAMP)
AND e.timestamp < CAST('${END_TIMESTAMP}' AS TIMESTAMP)
AND e.eventType = 'user_engagement'
),
normalized AS (
SELECT
COALESCE(NULLIF(le.event_id, ''), xdm_event_id) AS event_id,
le.event_version AS event_version,
COALESCE(CAST(le.event_timestamp AS TIMESTAMP), xdm_timestamp) AS event_timestamp,
le.reporting_window_id AS reporting_window_id,
CAST(le.reporting_window_start AS TIMESTAMP) AS reporting_window_start,
CAST(le.reporting_window_end AS TIMESTAMP) AS reporting_window_end,
le.learner_id AS learner_id,
le.anonymous_id AS anonymous_id,
le.identity_namespace AS identity_namespace,
le.identity_auth_state AS identity_auth_state,
le.session_id AS session_id,
le.engagement_id AS engagement_id,
le.enrollment_id AS enrollment_id,
le.course_id AS course_id,
le.course_name AS course_name,
le.course_version AS course_version,
le.learning_path_id AS learning_path_id,
le.module_id AS module_id,
le.lesson_id AS lesson_id,
le.activity_id AS activity_id,
le.activity_type AS activity_type,
le.content_id AS content_id,
le.content_type AS content_type,
le.content_title AS content_title,
le.content_provider AS content_provider,
le.content_language AS content_language,
le.delivery_channel AS delivery_channel,
le.platform AS platform,
le.device_type AS device_type,
le.app_id AS app_id,
le.app_version AS app_version,
le.page_location AS page_location,
le.page_referrer AS page_referrer,
NULLIF(le.media_id, '') AS media_id,
NULLIF(le.assessment_id, '') AS assessment_id,
NULLIF(le.lab_id, '') AS lab_id,
le.interaction_type AS interaction_type,
CAST(le.engagement_start_time AS TIMESTAMP) AS engagement_start_time,
CAST(le.engagement_end_time AS TIMESTAMP) AS engagement_end_time,
CAST(le.active_time_msec AS BIGINT) AS active_time_msec,
CAST(le.idle_time_msec AS BIGINT) AS idle_time_msec,
CAST(le.background_time_msec AS BIGINT) AS background_time_msec,
CAST(le.duplicate_time_msec AS BIGINT) AS duplicate_time_msec,
CAST(le.invalid_time_msec AS BIGINT) AS invalid_time_msec,
CAST(le.non_learning_time_msec AS BIGINT) AS non_learning_time_msec,
CAST(le.elapsed_time_msec AS BIGINT) AS elapsed_time_msec,
le.completion_status AS completion_status,
COALESCE(le.attribution_eligible, FALSE) AS attribution_eligible,
CAST(le.engagement_time_msec AS BIGINT) AS reported_engagement_time_msec,
xdm_timestamp AS ingestion_order_timestamp
FROM source_events
),
ranked AS (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY COALESCE(
NULLIF(event_id, ''),
CONCAT(
COALESCE(NULLIF(engagement_id, ''), 'unknown'), '|',
COALESCE(NULLIF(learner_id, ''), NULLIF(anonymous_id, ''), 'unknown'), '|',
CAST(event_timestamp AS VARCHAR)
)
)
ORDER BY ingestion_order_timestamp DESC
) AS duplicate_rank
FROM normalized
),
deduplicated AS (
SELECT *
FROM ranked
WHERE duplicate_rank = 1
),
measured AS (
SELECT
*,
COALESCE(
reported_engagement_time_msec,
active_time_msec,
GREATEST(
COALESCE(elapsed_time_msec, 0)
- COALESCE(idle_time_msec, 0)
- COALESCE(background_time_msec, 0)
- COALESCE(duplicate_time_msec, 0)
- COALESCE(invalid_time_msec, 0)
- COALESCE(non_learning_time_msec, 0),
0
)
) AS candidate_engagement_time_msec
FROM deduplicated
)
SELECT
event_id,
event_version,
event_timestamp,
reporting_window_id,
reporting_window_start,
reporting_window_end,
learner_id,
anonymous_id,
identity_namespace,
identity_auth_state,
session_id,
engagement_id,
enrollment_id,
course_id,
course_name,
course_version,
learning_path_id,
module_id,
lesson_id,
activity_id,
activity_type,
content_id,
content_type,
content_title,
content_provider,
content_language,
delivery_channel,
platform,
device_type,
app_id,
app_version,
page_location,
page_referrer,
media_id,
assessment_id,
lab_id,
interaction_type,
engagement_start_time,
engagement_end_time,
active_time_msec,
idle_time_msec,
background_time_msec,
duplicate_time_msec,
invalid_time_msec,
non_learning_time_msec,
elapsed_time_msec,
completion_status,
attribution_eligible,
CASE
WHEN attribution_eligible THEN GREATEST(
LEAST(
candidate_engagement_time_msec,
COALESCE(elapsed_time_msec, candidate_engagement_time_msec)
),
0
)
ELSE 0
END AS engagement_time_msec,
CAST(
CASE
WHEN attribution_eligible THEN GREATEST(
LEAST(candidate_engagement_time_msec, COALESCE(elapsed_time_msec, candidate_engagement_time_msec)),
0
)
ELSE 0
END AS DOUBLE
) / 1000.0 AS engagement_time_seconds,
CAST(
CASE
WHEN attribution_eligible THEN GREATEST(
LEAST(candidate_engagement_time_msec, COALESCE(elapsed_time_msec, candidate_engagement_time_msec)),
0
)
ELSE 0
END AS DOUBLE
) / 60000.0 AS engagement_time_minutes
FROM measured;Source Data
Learning Management System event stream, web and mobile Digital Analytics, video and media telemetry, assessment platform events, virtual lab or simulation logs, enrollment records, and identity-resolution services
Dependencies
[ "learner_id", "event_id", "event_type", "event_timestamp", "engagement_interval_start", "engagement_interval_end", "engagement_duration_seconds", "content_id", "course_id", "session_id", "device_id", "application_visibility_state", "media_playback_state", "enrollment_status", "reporting_timezone", "eligible_learning_event" ]
Report Attributes
Course Program Subject Module Lesson Content Item Content Type Learning Activity Type Delivery Mode Learner Cohort Enrollment Status Subscription Plan Institution Instructor Device Type Operating System Application Version Geography Acquisition Channel Session Type Calendar Date Academic Term
Recommended Reporting Views
Segment Eligibility
true
Governance
Derived KPIs
Governance
GitHub
catalog/metrics/learner-engagement-time.yml