Docs For AI
Monitoring

Real User Monitoring

Measuring actual user experience with RUM and Core Web Vitals

Real User Monitoring (RUM)

RUM captures and analyzes real user interactions, providing insights into actual user experience across different devices, networks, and locations.

RUM vs Synthetic Monitoring

AspectRUMSynthetic
Data SourceReal usersSimulated requests
CoverageAll user conditionsControlled environment
TimingReactive (after issues)Proactive (before users)
CostScales with trafficFixed cost
Use CaseProduction monitoringPre-release testing

Core Web Vitals

LCP (Largest Contentful Paint)

Measures loading performance - when the main content becomes visible.

// Using web-vitals library
import { onLCP } from 'web-vitals';

onLCP((metric) => {
  console.log('LCP:', metric.value);
  // Send to analytics
  analytics.track('web-vital', {
    name: 'LCP',
    value: metric.value,
    rating: metric.rating, // 'good', 'needs-improvement', 'poor'
  });
});

Optimization targets:

  • Good: < 2.5s
  • Needs Improvement: 2.5s - 4.0s
  • Poor: > 4.0s

INP (Interaction to Next Paint)

Measures responsiveness - delay between user interaction and visual feedback.

import { onINP } from 'web-vitals';

onINP((metric) => {
  console.log('INP:', metric.value);
  // Log the interaction that caused the INP
  console.log('Attribution:', metric.attribution);
});

Optimization targets:

  • Good: < 200ms
  • Needs Improvement: 200ms - 500ms
  • Poor: > 500ms

CLS (Cumulative Layout Shift)

Measures visual stability - unexpected layout shifts during page load.

import { onCLS } from 'web-vitals';

onCLS((metric) => {
  console.log('CLS:', metric.value);
  // Log elements that shifted
  metric.entries.forEach((entry) => {
    console.log('Shifted element:', entry.sources);
  });
});

Optimization targets:

  • Good: < 0.1
  • Needs Improvement: 0.1 - 0.25
  • Poor: > 0.25

Implementation

web-vitals Library

import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';

function sendToAnalytics(metric) {
  const body = JSON.stringify({
    name: metric.name,
    value: metric.value,
    rating: metric.rating,
    delta: metric.delta,
    id: metric.id,
    navigationType: metric.navigationType,
  });

  // Use sendBeacon for reliability
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/analytics', body);
  } else {
    fetch('/analytics', { body, method: 'POST', keepalive: true });
  }
}

onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);
onFCP(sendToAnalytics);
onTTFB(sendToAnalytics);

Custom Performance Metrics

// Measure custom user timing
performance.mark('feature-start');

// ... feature code ...

performance.mark('feature-end');
performance.measure('feature-duration', 'feature-start', 'feature-end');

const measure = performance.getEntriesByName('feature-duration')[0];
console.log('Feature took:', measure.duration, 'ms');

Session Tracking

// Track user session with context
const sessionContext = {
  sessionId: generateSessionId(),
  userId: getUserId(),
  device: getDeviceType(),
  connection: navigator.connection?.effectiveType,
  viewport: `${window.innerWidth}x${window.innerHeight}`,
};

function trackMetric(metric) {
  sendToAnalytics({
    ...metric,
    ...sessionContext,
    timestamp: Date.now(),
    url: window.location.href,
  });
}

Data Analysis

Percentile Analysis

Use percentiles instead of averages:

PercentileUse Case
P50 (Median)Typical user experience
P75Google's Core Web Vitals threshold
P90Degraded experience
P99Worst-case scenarios

Segmentation

Analyze metrics by:

  • Device Type: Mobile vs Desktop
  • Browser: Chrome, Safari, Firefox
  • Geography: Region, country
  • Connection: 4G, 3G, WiFi
  • Page Type: Landing, product, checkout

Alerting Thresholds

MetricWarningCritical
LCP P75> 2.5s> 4.0s
INP P75> 200ms> 500ms
CLS P75> 0.1> 0.25
Error Rate> 0.5%> 1%
Page Load P75> 3s> 5s

Tools Integration

ToolStrengths
Google Analytics 4Free, Core Web Vitals built-in
Datadog RUMFull-stack correlation
New Relic BrowserAPM integration
SpeedCurvePerformance budgets
DebugBearWeb Vitals focus

On this page