Homeโ€บ๐Ÿ” DQL & Data Accessโ€บModule 71 min read ยท 8/21

USQL โ†’ DQL for RUM Data

Hands-on3 exercises

USQL โ†’ DQL for RUM Data

Gen2 used USQL (User Session Query Language) to analyze Real User Monitoring data. Gen3 replaces it entirely with DQL using fetch user.events and fetch user.sessions.

Side-by-Side

USQL (Gen2)                             DQL (Gen3)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
SELECT browserType, COUNT(*)            fetch user.events
FROM usersession                        | filter characteristics.has_page_summary == true
GROUP BY browserType                    | summarize count(), by:{browser.name}

SELECT AVG(duration)                    fetch user.events
FROM useraction                         | filter characteristics.has_navigation == true
WHERE application = "MyApp"             | filter frontend.name == "MyApp"
                                        | summarize avg_duration = avg(duration)

SELECT TOP 10 name, AVG(duration)       fetch user.events
FROM useraction                         | filter characteristics.has_page_summary == true
GROUP BY name                           | summarize avg_dur = avg(duration), by:{page.url.path}
ORDER BY AVG(duration) DESC             | sort avg_dur desc
                                        | limit 10

Data Source Mapping

USQL Table                              DQL Data Object
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
usersession                             fetch user.sessions
useraction                              fetch user.events (+ characteristics filter)
userevent                               fetch user.events
๐Ÿ›  Try it

Convert this USQL query to DQL: SELECT browserType, COUNT(*) FROM usersession GROUP BY browserType

extension.yamlYAML
Loading...

Key Field Differences

USQL Field                              DQL Field
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
browserType                             browser.name
osFamily                                os.name
city, country                           geo.country.iso_code
duration                                duration (nanoseconds in sessions!)
application                             frontend.name
userSessionId                           dt.rum.session.id
userId                                  dt.rum.user_tag
bounce                                  characteristics.is_bounce

Important: Session Time Windows

fetch user.sessions only returns sessions that started in the query window โ€” not sessions active during it. Sessions can last 8+ hours. For correlation queries, extend lookback by at least 8 hours.

Session Field Naming

Session fields use underscores, not dots:

โœ… navigation_count          โŒ navigation.count
โœ… user_interaction_count    โŒ user_interaction.count
โœ… request_count             โŒ request.count
โœ… page_summary_count        โŒ page_summary.count

Bounce Rate Example

fetch user.sessions, from:now() - 24h
| filter dt.rum.user_type == "real_user"
| summarize
    total = count(),
    bounces = countIf(characteristics.is_bounce == true),
    avg_duration_s = avg(toLong(duration)) / 1000000000
| fieldsAdd bounce_rate = round((bounces * 100.0) / total, decimals: 1)