[{"data":1,"prerenderedAt":1118},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection":1109},{"id":4,"title":5,"body":6,"description":1089,"extension":1090,"meta":1091,"navigation":1102,"path":1103,"seo":1104,"stem":1107,"__hash__":1108},"content\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection\u002Findex.md","Segmenting RUM by Device and Connection",{"type":7,"value":8,"toc":1074},"minimark",[9,14,29,32,126,131,175,179,185,191,201,207,301,305,310,597,600,604,607,755,762,766,778,781,785,788,820,823,952,956,959,963,970,974,977,981,993,1014,1023,1032,1036,1059,1064,1067,1070],[10,11,13],"h1",{"id":12},"how-to-segment-rum-data-by-device-and-connection","How to Segment RUM Data by Device and Connection",[15,16,17,18,23,24,28],"p",{},"This guide extends ",[19,20,22],"a",{"href":21},"\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002F","RUM Beacons & Field Data Collection"," within ",[19,25,27],{"href":26},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement",". A p75 that fails tells you there is a problem; it does not tell you who has it. The slow quarter of page views is almost never a uniform slice of your audience — it is concentrated in particular devices, networks, countries and page templates. Segmentation turns \"INP is 280ms\" into \"INP is 450ms on 4GB Android devices and 140ms everywhere else\", which tells you to reduce main-thread work rather than bytes.",[15,30,31],{},"The difficulty is that the most useful dimensions are partly browser-specific, partly coarse by design (for privacy), and easy to collect in ways that inflate cardinality. This guide covers which signals to capture, how to bucket them into a small number of meaningful classes, and how to read the result.",[15,33,34],{},[35,36,42,43,42,50,42,54,42,57,42,66,42,72,42,80,42,86,42,92,42,95,42,99,42,102,42,106,42,110,42,113,42,119,42,123,42],"svg",{"viewBox":37,"width":38,"role":39,"ariaLabel":40,"style":41},"0 0 760 268","100%","img","Layers of device, network, context and page dimensions that make RUM data segmentable.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[44,45],"rect",{"className":46,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],"svg-canvas","0","#ffffff",[51,52,53],"title",{},"Dimensions worth capturing with every beacon",[55,56,40],"desc",{},[44,58],{"x":59,"y":59,"width":60,"height":61,"rx":62,"fill":63,"stroke":64,"style":65},"1","758","266","10","none","currentColor","stroke-opacity:0.18",[67,68,53],"text",{"x":69,"y":70,"fill":64,"style":71},"28.0","34.0","font-size:16px;font-weight:700",[44,73],{"x":69,"y":74,"width":75,"height":76,"rx":77,"fill":78,"stroke":78,"style":79},"56.0","704.0","40.0","6","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[67,81,85],{"x":82,"y":83,"fill":64,"style":84},"42.0","80.5","font-size:13px;font-weight:700","Device",[67,87,91],{"x":88,"y":83,"fill":64,"style":89,"textAnchor":90},"113.4","font-size:12px","start","deviceMemory, hardwareConcurrency, form factor (Client Hints or UA)",[44,93],{"x":69,"y":94,"width":75,"height":76,"rx":77,"fill":78,"stroke":78,"style":79},"106.0",[67,96,98],{"x":82,"y":97,"fill":64,"style":84},"130.5","Network",[67,100,101],{"x":88,"y":97,"fill":64,"style":89,"textAnchor":90},"effectiveType, rtt, downlink (Chromium), plus measured TTFB",[44,103],{"x":69,"y":104,"width":75,"height":76,"rx":77,"fill":64,"stroke":64,"style":105},"156.0","fill-opacity:0.06;stroke-opacity:0.4",[67,107,109],{"x":82,"y":108,"fill":64,"style":84},"180.5","Context",[67,111,112],{"x":88,"y":108,"fill":64,"style":89,"textAnchor":90},"country, navigation type, first vs repeat visit, logged-in",[44,114],{"x":69,"y":115,"width":75,"height":76,"rx":77,"fill":116,"stroke":117,"style":118},"206.0","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[67,120,122],{"x":82,"y":121,"fill":64,"style":84},"230.5","Page",[67,124,125],{"x":88,"y":121,"fill":64,"style":89,"textAnchor":90},"route template, release id, A\u002FB variant",[127,128,130],"h2",{"id":129},"rapid-diagnosis","Rapid Diagnosis",[132,133,134,142,156,169],"ul",{},[135,136,137,141],"li",{},[138,139,140],"strong",{},"Check what your beacon contains today."," Many beacons carry only URL and metric values. Without device and network context, segmentation is impossible after the fact.",[135,143,144,42,147,151,152,155],{},[138,145,146],{},"Look at your browser mix.",[148,149,150],"code",{},"navigator.deviceMemory"," and ",[148,153,154],{},"navigator.connection"," are Chromium-only. For Safari-heavy audiences you need derived signals (measured TTFB, resource timings).",[135,157,158,161,162,151,165,168],{},[138,159,160],{},"Check cardinality."," Raw ",[148,163,164],{},"rtt",[148,166,167],{},"downlink"," values, full user-agent strings and precise geo produce thousands of distinct values. Bucket them before storage.",[135,170,171,174],{},[138,172,173],{},"Compare segment p75s."," Even a crude split (mobile vs desktop × \"low\" vs \"high\" memory) usually reveals where the slow tail lives.",[127,176,178],{"id":177},"root-cause-analysis","Root Cause Analysis",[15,180,181,184],{},[138,182,183],{},"1. Missing context."," Beacons without device or network fields cannot be segmented, so analysis falls back to averages that hide the problem.",[15,186,187,190],{},[138,188,189],{},"2. Unbucketed values."," Storing raw RTT in milliseconds or full UA strings creates high-cardinality columns that are expensive to query and impossible to read in a dashboard.",[15,192,193,196,197,200],{},[138,194,195],{},"3. Browser-specific signals treated as universal."," Segmenting on ",[148,198,199],{},"deviceMemory"," silently excludes Safari and Firefox users; conclusions drawn from it describe Chromium only.",[15,202,203,206],{},[138,204,205],{},"4. Confounding."," Slow devices are more common in some countries and on some templates. A device effect can actually be a template effect if not controlled for.",[15,208,209],{},[35,210,42,213,42,216,42,219,42,221,42,224,42,226,42,236,42,243,42,251,42,256,42,260,42,264,42,268,42,272,42,277,42,281,42,285,42,290,42,294,42],{"viewBox":211,"width":38,"role":39,"ariaLabel":212,"style":41},"0 0 760 216","Bar chart of mobile p75 INP split by reported device memory, showing low-memory devices far above the 200 millisecond threshold.",[44,214],{"className":215,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,217,218],{},"Mobile INP p75 by device memory class",[55,220,212],{},[44,222],{"x":59,"y":59,"width":60,"height":223,"rx":62,"fill":63,"stroke":64,"style":65},"214",[67,225,218],{"x":69,"y":70,"fill":64,"style":71},[227,228],"line",{"x1":229,"y1":230,"x2":229,"y2":231,"stroke":117,"strokeWidth":232,"strokeDashArray":233,"style":235},"375.8","72.0","194.0","1.5",[234,234],"4","stroke-opacity:0.9",[67,237,242],{"x":238,"y":239,"fill":64,"style":240,"textAnchor":241},"176.4","92.0","font-size:13px","end","≤ 2 GB",[44,244],{"x":245,"y":246,"width":247,"height":248,"rx":249,"fill":116,"stroke":117,"style":250},"188.4","78.0","479.6","19","3","fill-opacity:0.7;stroke-opacity:0.9",[67,252,255],{"x":253,"y":239,"fill":64,"style":254},"674.0","font-size:12px;font-weight:600","512ms",[67,257,259],{"x":238,"y":258,"fill":64,"style":240,"textAnchor":241},"123.0","4 GB",[44,261],{"x":245,"y":262,"width":263,"height":248,"rx":249,"fill":116,"stroke":117,"style":250},"109.0","297.9",[67,265,267],{"x":266,"y":258,"fill":64,"style":254},"492.3","318ms",[67,269,271],{"x":238,"y":270,"fill":64,"style":240,"textAnchor":241},"154.0","8 GB",[44,273],{"x":245,"y":274,"width":275,"height":248,"rx":249,"fill":78,"stroke":78,"style":276},"140.0","144.2","fill-opacity:0.55;stroke-opacity:0.9",[67,278,280],{"x":279,"y":270,"fill":64,"style":254},"338.7","154ms",[67,282,284],{"x":238,"y":283,"fill":64,"style":240,"textAnchor":241},"185.0","Unknown (Safari, Firefox)",[44,286],{"x":245,"y":287,"width":288,"height":248,"rx":249,"fill":64,"stroke":64,"style":289},"171.0","160.2","fill-opacity:0.7;stroke-opacity:0.4",[67,291,293],{"x":292,"y":283,"fill":64,"style":254},"354.6","171ms",[67,295,300],{"x":229,"y":296,"fill":297,"style":298,"textAnchor":299},"68.0","#8a6608","font-size:12px;font-weight:700","middle","200ms INP",[127,302,304],{"id":303},"step-by-step-resolution","Step-by-Step Resolution",[306,307,309],"h3",{"id":308},"_1-collect-device-and-network-context-once-per-page-view","1. Collect device and network context once per page view",[311,312,317],"pre",{"className":313,"code":314,"language":315,"meta":316,"style":316},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","function context() {\n  const c = navigator.connection || {};\n  const nav = performance.getEntriesByType('navigation')[0];\n  return {\n    mem: navigator.deviceMemory ?? null,                       \u002F\u002F 0.25..8, Chromium only\n    cores: navigator.hardwareConcurrency ?? null,\n    ect: c.effectiveType ?? null,                              \u002F\u002F 'slow-2g'..'4g'\n    rttBucket: c.rtt != null ? Math.min(Math.ceil(c.rtt \u002F 100) * 100, 1000) : null,\n    ttfbBucket: nav ? Math.min(Math.ceil(nav.responseStart \u002F 200) * 200, 4000) : null,\n    mobile: navigator.userAgentData?.mobile ?? \u002FMobi\u002F.test(navigator.userAgent),\n  };\n}\n\u002F\u002F trade-off: deviceMemory and hardwareConcurrency are rounded and capped by the\n\u002F\u002F browser for privacy (memory tops out at 8). They separate low-end from\n\u002F\u002F mid-range well, but cannot distinguish a mid-range phone from a flagship.\n","javascript","",[148,318,319,335,357,388,397,416,429,445,503,547,567,573,579,585,591],{"__ignoreMap":316},[320,321,323,327,331],"span",{"class":227,"line":322},1,[320,324,326],{"class":325},"sPARh","function",[320,328,330],{"class":329},"smZ65"," context",[320,332,334],{"class":333},"saISM","() {\n",[320,336,338,341,345,348,351,354],{"class":227,"line":337},2,[320,339,340],{"class":325},"  const",[320,342,344],{"class":343},"sPXB4"," c",[320,346,347],{"class":325}," =",[320,349,350],{"class":333}," navigator.connection ",[320,352,353],{"class":325},"||",[320,355,356],{"class":333}," {};\n",[320,358,360,362,365,367,370,373,376,380,383,385],{"class":227,"line":359},3,[320,361,340],{"class":325},[320,363,364],{"class":343}," nav",[320,366,347],{"class":325},[320,368,369],{"class":333}," performance.",[320,371,372],{"class":329},"getEntriesByType",[320,374,375],{"class":333},"(",[320,377,379],{"class":378},"sZ8jY","'navigation'",[320,381,382],{"class":333},")[",[320,384,48],{"class":343},[320,386,387],{"class":333},"];\n",[320,389,391,394],{"class":227,"line":390},4,[320,392,393],{"class":325},"  return",[320,395,396],{"class":333}," {\n",[320,398,400,403,406,409,412],{"class":227,"line":399},5,[320,401,402],{"class":333},"    mem: navigator.deviceMemory ",[320,404,405],{"class":325},"??",[320,407,408],{"class":343}," null",[320,410,411],{"class":333},",                       ",[320,413,415],{"class":414},"sjfSM","\u002F\u002F 0.25..8, Chromium only\n",[320,417,419,422,424,426],{"class":227,"line":418},6,[320,420,421],{"class":333},"    cores: navigator.hardwareConcurrency ",[320,423,405],{"class":325},[320,425,408],{"class":343},[320,427,428],{"class":333},",\n",[320,430,432,435,437,439,442],{"class":227,"line":431},7,[320,433,434],{"class":333},"    ect: c.effectiveType ",[320,436,405],{"class":325},[320,438,408],{"class":343},[320,440,441],{"class":333},",                              ",[320,443,444],{"class":414},"\u002F\u002F 'slow-2g'..'4g'\n",[320,446,448,451,454,456,459,462,465,468,471,474,477,480,483,486,488,491,494,496,499,501],{"class":227,"line":447},8,[320,449,450],{"class":333},"    rttBucket: c.rtt ",[320,452,453],{"class":325},"!=",[320,455,408],{"class":343},[320,457,458],{"class":325}," ?",[320,460,461],{"class":333}," Math.",[320,463,464],{"class":329},"min",[320,466,467],{"class":333},"(Math.",[320,469,470],{"class":329},"ceil",[320,472,473],{"class":333},"(c.rtt ",[320,475,476],{"class":325},"\u002F",[320,478,479],{"class":343}," 100",[320,481,482],{"class":333},") ",[320,484,485],{"class":325},"*",[320,487,479],{"class":343},[320,489,490],{"class":333},", ",[320,492,493],{"class":343},"1000",[320,495,482],{"class":333},[320,497,498],{"class":325},":",[320,500,408],{"class":343},[320,502,428],{"class":333},[320,504,506,509,512,514,516,518,520,523,525,528,530,532,534,536,539,541,543,545],{"class":227,"line":505},9,[320,507,508],{"class":333},"    ttfbBucket: nav ",[320,510,511],{"class":325},"?",[320,513,461],{"class":333},[320,515,464],{"class":329},[320,517,467],{"class":333},[320,519,470],{"class":329},[320,521,522],{"class":333},"(nav.responseStart ",[320,524,476],{"class":325},[320,526,527],{"class":343}," 200",[320,529,482],{"class":333},[320,531,485],{"class":325},[320,533,527],{"class":343},[320,535,490],{"class":333},[320,537,538],{"class":343},"4000",[320,540,482],{"class":333},[320,542,498],{"class":325},[320,544,408],{"class":343},[320,546,428],{"class":333},[320,548,550,553,555,558,561,564],{"class":227,"line":549},10,[320,551,552],{"class":333},"    mobile: navigator.userAgentData?.mobile ",[320,554,405],{"class":325},[320,556,557],{"class":378}," \u002FMobi\u002F",[320,559,560],{"class":333},".",[320,562,563],{"class":329},"test",[320,565,566],{"class":333},"(navigator.userAgent),\n",[320,568,570],{"class":227,"line":569},11,[320,571,572],{"class":333},"  };\n",[320,574,576],{"class":227,"line":575},12,[320,577,578],{"class":333},"}\n",[320,580,582],{"class":227,"line":581},13,[320,583,584],{"class":414},"\u002F\u002F trade-off: deviceMemory and hardwareConcurrency are rounded and capped by the\n",[320,586,588],{"class":227,"line":587},14,[320,589,590],{"class":414},"\u002F\u002F browser for privacy (memory tops out at 8). They separate low-end from\n",[320,592,594],{"class":227,"line":593},15,[320,595,596],{"class":414},"\u002F\u002F mid-range well, but cannot distinguish a mid-range phone from a flagship.\n",[15,598,599],{},"Expected outcome: every beacon carries a handful of low-cardinality fields that cover device and network.",[306,601,603],{"id":602},"_2-derive-a-device-class-that-works-across-browsers","2. Derive a device class that works across browsers",[15,605,606],{},"Combine signals into a small set of classes, with a fallback for browsers that expose less.",[311,608,610],{"className":313,"code":609,"language":315,"meta":316,"style":316},"function deviceClass(ctx) {\n  if (ctx.mem != null) return ctx.mem \u003C= 2 ? 'low' : ctx.mem \u003C= 4 ? 'mid' : 'high';\n  if (ctx.cores != null) return ctx.cores \u003C= 4 ? 'low' : ctx.cores \u003C= 6 ? 'mid' : 'high';\n  return 'unknown';\n}\n\u002F\u002F trade-off: core counts on iPhones are modest (6) while their per-core speed is\n\u002F\u002F high, so cores alone misclassify iOS devices as \"mid\". Keep \"unknown\" honest\n\u002F\u002F rather than forcing every device into a class.\n",[148,611,612,628,682,727,736,740,745,750],{"__ignoreMap":316},[320,613,614,616,619,621,625],{"class":227,"line":322},[320,615,326],{"class":325},[320,617,618],{"class":329}," deviceClass",[320,620,375],{"class":333},[320,622,624],{"class":623},"sQw3B","ctx",[320,626,627],{"class":333},") {\n",[320,629,630,633,636,638,640,642,645,648,651,654,656,659,662,664,666,669,671,674,676,679],{"class":227,"line":337},[320,631,632],{"class":325},"  if",[320,634,635],{"class":333}," (ctx.mem ",[320,637,453],{"class":325},[320,639,408],{"class":343},[320,641,482],{"class":333},[320,643,644],{"class":325},"return",[320,646,647],{"class":333}," ctx.mem ",[320,649,650],{"class":325},"\u003C=",[320,652,653],{"class":343}," 2",[320,655,458],{"class":325},[320,657,658],{"class":378}," 'low'",[320,660,661],{"class":325}," :",[320,663,647],{"class":333},[320,665,650],{"class":325},[320,667,668],{"class":343}," 4",[320,670,458],{"class":325},[320,672,673],{"class":378}," 'mid'",[320,675,661],{"class":325},[320,677,678],{"class":378}," 'high'",[320,680,681],{"class":333},";\n",[320,683,684,686,689,691,693,695,697,700,702,704,706,708,710,712,714,717,719,721,723,725],{"class":227,"line":359},[320,685,632],{"class":325},[320,687,688],{"class":333}," (ctx.cores ",[320,690,453],{"class":325},[320,692,408],{"class":343},[320,694,482],{"class":333},[320,696,644],{"class":325},[320,698,699],{"class":333}," ctx.cores ",[320,701,650],{"class":325},[320,703,668],{"class":343},[320,705,458],{"class":325},[320,707,658],{"class":378},[320,709,661],{"class":325},[320,711,699],{"class":333},[320,713,650],{"class":325},[320,715,716],{"class":343}," 6",[320,718,458],{"class":325},[320,720,673],{"class":378},[320,722,661],{"class":325},[320,724,678],{"class":378},[320,726,681],{"class":333},[320,728,729,731,734],{"class":227,"line":390},[320,730,393],{"class":325},[320,732,733],{"class":378}," 'unknown'",[320,735,681],{"class":333},[320,737,738],{"class":227,"line":399},[320,739,578],{"class":333},[320,741,742],{"class":227,"line":418},[320,743,744],{"class":414},"\u002F\u002F trade-off: core counts on iPhones are modest (6) while their per-core speed is\n",[320,746,747],{"class":227,"line":431},[320,748,749],{"class":414},"\u002F\u002F high, so cores alone misclassify iOS devices as \"mid\". Keep \"unknown\" honest\n",[320,751,752],{"class":227,"line":447},[320,753,754],{"class":414},"\u002F\u002F rather than forcing every device into a class.\n",[15,756,757,758,761],{},"Expected outcome: a three- or four-value ",[148,759,760],{},"deviceClass"," column that most dashboards can split by.",[306,763,765],{"id":764},"_3-use-measured-network-timings-for-all-browsers","3. Use measured network timings for all browsers",[15,767,768,151,771,773,774,777],{},[148,769,770],{},"effectiveType",[148,772,164],{}," are unavailable outside Chromium, but every browser exposes Navigation Timing. Bucketed TTFB and the connection phases (",[148,775,776],{},"connectEnd - connectStart",") are cross-browser proxies for network quality.",[15,779,780],{},"Expected outcome: a network dimension that covers Safari users too.",[306,782,784],{"id":783},"_4-segment-then-control-for-confounders","4. Segment, then control for confounders",[15,786,787],{},"Compute p75 per segment, and before drawing conclusions, check that the comparison holds within a template and within a country.",[311,789,793],{"className":790,"code":791,"language":792,"meta":316,"style":316},"language-sql shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","SELECT template, device_class, APPROX_QUANTILES(inp, 100)[OFFSET(75)] AS p75_inp, COUNT(*) AS n\nFROM rum.final WHERE metric = 'INP' AND mobile\nGROUP BY 1, 2 HAVING n > 1000 ORDER BY template, device_class;\n-- trade-off: crossing many dimensions quickly runs out of samples. Cross two\n-- at a time, and only add a third for segments with ample traffic.\n","sql",[148,794,795,800,805,810,815],{"__ignoreMap":316},[320,796,797],{"class":227,"line":322},[320,798,799],{},"SELECT template, device_class, APPROX_QUANTILES(inp, 100)[OFFSET(75)] AS p75_inp, COUNT(*) AS n\n",[320,801,802],{"class":227,"line":337},[320,803,804],{},"FROM rum.final WHERE metric = 'INP' AND mobile\n",[320,806,807],{"class":227,"line":359},[320,808,809],{},"GROUP BY 1, 2 HAVING n > 1000 ORDER BY template, device_class;\n",[320,811,812],{"class":227,"line":390},[320,813,814],{},"-- trade-off: crossing many dimensions quickly runs out of samples. Cross two\n",[320,816,817],{"class":227,"line":399},[320,818,819],{},"-- at a time, and only add a third for segments with ample traffic.\n",[15,821,822],{},"Expected outcome: a defensible statement such as \"low-memory devices fail INP on product and search templates, but not on articles\", which points directly at JavaScript cost on interactive templates.",[15,824,825],{},[35,826,42,829,42,832,42,835,42,837,42,840,42,842,42,846,42,852,42,856,42,860,42,863,42,867,42,872,42,876,42,880,42,882,42,886,42,888,42,891,42,894,42,898,42,902,42,904,42,908,42,910,42,913,42,916,42,920,42,924,42,926,42,930,42,932,42,935,42,938,42,942,42,944,42,947,42,949,42],{"viewBox":827,"width":38,"role":39,"ariaLabel":828,"style":41},"0 0 760 276","How the pattern of a failing metric across device and network segments points to a likely cause.",[44,830],{"className":831,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,833,834],{},"Reading a segmented result",[55,836,828],{},[44,838],{"x":59,"y":59,"width":60,"height":839,"rx":62,"fill":63,"stroke":64,"style":65},"274",[67,841,834],{"x":69,"y":70,"fill":64,"style":71},[44,843],{"x":69,"y":74,"width":844,"height":845,"rx":48,"fill":64,"stroke":64,"style":105},"210.0","30.0",[67,847,851],{"x":848,"y":849,"fill":64,"style":850,"textAnchor":90},"38.0","75.5","font-size:12.5px;font-weight:700","Pattern in segments",[44,853],{"x":854,"y":74,"width":855,"height":845,"rx":48,"fill":64,"stroke":64,"style":105},"238.0","247.0",[67,857,859],{"x":858,"y":849,"fill":64,"style":850,"textAnchor":299},"361.5","Likely cause",[44,861],{"x":862,"y":74,"width":855,"height":845,"rx":48,"fill":64,"stroke":64,"style":105},"485.0",[67,864,866],{"x":865,"y":849,"fill":64,"style":850,"textAnchor":299},"608.5","Fix family",[44,868],{"x":69,"y":869,"width":844,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},"86.0","46.0","stroke-opacity:0.35",[67,873,875],{"x":848,"y":874,"fill":64,"style":850,"textAnchor":90},"105.5","Fails on low-memory devices",[67,877,879],{"x":848,"y":878,"fill":64,"style":850,"textAnchor":90},"121.5","only",[44,881],{"x":854,"y":869,"width":855,"height":870,"rx":48,"fill":116,"stroke":117,"style":118},[67,883,885],{"x":858,"y":884,"fill":64,"style":89,"textAnchor":299},"113.5","main-thread work",[44,887],{"x":862,"y":869,"width":855,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},[67,889,890],{"x":865,"y":884,"fill":64,"style":89,"textAnchor":299},"Less JS, yield, workers",[44,892],{"x":69,"y":893,"width":844,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},"132.0",[67,895,897],{"x":848,"y":896,"fill":64,"style":850,"textAnchor":90},"151.5","Fails on high-RTT",[67,899,901],{"x":848,"y":900,"fill":64,"style":850,"textAnchor":90},"167.5","connections only",[44,903],{"x":854,"y":893,"width":855,"height":870,"rx":48,"fill":116,"stroke":117,"style":118},[67,905,907],{"x":858,"y":906,"fill":64,"style":89,"textAnchor":299},"159.5","round trips",[44,909],{"x":862,"y":893,"width":855,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},[67,911,912],{"x":865,"y":906,"fill":64,"style":89,"textAnchor":299},"Preconnect, early hints, fewer hops",[44,914],{"x":69,"y":915,"width":844,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},"178.0",[67,917,919],{"x":848,"y":918,"fill":64,"style":850,"textAnchor":90},"197.5","Fails on one template",[67,921,923],{"x":848,"y":922,"fill":64,"style":850,"textAnchor":90},"213.5","everywhere",[44,925],{"x":854,"y":915,"width":855,"height":870,"rx":48,"fill":116,"stroke":117,"style":118},[67,927,929],{"x":858,"y":928,"fill":64,"style":89,"textAnchor":299},"205.5","template code",[44,931],{"x":862,"y":915,"width":855,"height":870,"rx":48,"fill":63,"stroke":64,"style":871},[67,933,934],{"x":865,"y":928,"fill":64,"style":89,"textAnchor":299},"Profile that template",[44,936],{"x":69,"y":937,"width":844,"height":845,"rx":48,"fill":63,"stroke":64,"style":871},"224.0",[67,939,941],{"x":848,"y":940,"fill":64,"style":850,"textAnchor":90},"243.5","Fails everywhere equally",[44,943],{"x":854,"y":937,"width":855,"height":845,"rx":48,"fill":64,"stroke":64,"style":105},[67,945,946],{"x":858,"y":940,"fill":64,"style":89,"textAnchor":299},"shared asset or server",[44,948],{"x":862,"y":937,"width":855,"height":845,"rx":48,"fill":63,"stroke":64,"style":871},[67,950,951],{"x":865,"y":940,"fill":64,"style":89,"textAnchor":299},"TTFB, global CSS\u002FJS",[127,953,955],{"id":954},"verification","Verification",[15,957,958],{},"Check that segment counts add up to the total and that the \"unknown\" share matches your non-Chromium traffic. Confirm stability: a segment's p75 should not swing wildly day to day if it has enough samples. After shipping a fix targeted at a segment (say, reducing hydration work for low-memory devices), that segment's p75 should move most; if every segment moves equally, the fix was broader than you thought — or the change was something else.",[127,960,962],{"id":961},"using-client-hints-for-server-side-segmentation","Using Client Hints for Server-Side Segmentation",[15,964,965,966,969],{},"Client Hints let the server see device signals on the request itself, which is useful for joining RUM with server logs and for serving lighter experiences. Request them with ",[148,967,968],{},"Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Device-Memory, ECT, RTT"," (subject to browser support and permissions policy), and log them alongside the request id that you also put in the page for the beacon. This gives you device context for page views where the beacon never arrived — the visits most likely to be slow — and lets you compare server-side counts with received beacons by segment to measure delivery bias. Respect privacy: request only the hints you use, and do not combine them into fingerprint-like identifiers.",[127,971,973],{"id":972},"turning-segments-into-lab-profiles","Turning Segments into Lab Profiles",[15,975,976],{},"Segmentation pays off twice: once in explaining the field number, and again in making lab testing realistic. For each segment that matters — \"low-memory Android on 4G\", say — record the p75 RTT, bandwidth and an approximate CPU slowdown, and create a named throttling profile from them in your Lighthouse CI and Playwright configuration. Running scripted tests under the profile of the failing segment reproduces its problems far more reliably than a generic \"Slow 4G\" preset, and the profile can be refreshed quarterly from the same RUM queries as your audience changes.",[127,978,980],{"id":979},"faq","FAQ",[982,983,986,990],"details",{"className":984},[985],"faq-item",[987,988,989],"summary",{},"Is it acceptable to collect device memory under privacy rules?",[15,991,992],{},"The values are coarse by design and are commonly treated as non-identifying technical data, but your organisation's privacy review decides. Keep them bucketed, do not combine many dimensions into a high-entropy profile, and document the purpose. Avoid collecting precise model names unless you have a concrete need.",[982,994,996,999],{"className":995},[985],[987,997,998],{},"Why does effectiveType say 4g for users on slow networks?",[15,1000,1001,1003,1004,1007,1008,1010,1011,1013],{},[148,1002,770],{}," is derived from recently observed round-trip times and throughput, capped at ",[148,1005,1006],{},"4g",". Most modern connections report ",[148,1009,1006],{}," even when they are congested or high-latency. Bucketed ",[148,1012,164],{}," and measured TTFB are more discriminating for typical web traffic.",[982,1015,1017,1020],{"className":1016},[985],[987,1018,1019],{},"Should segments drive different experiences, not just analysis?",[15,1021,1022],{},"They can. Serving fewer non-essential widgets, smaller images or simpler animations to low-memory devices is a legitimate optimisation, sometimes called adaptive loading. Make sure the core content and functionality are identical, and that the segment detection fails safe (towards the lighter experience) when signals are missing.",[982,1024,1026,1029],{"className":1025},[985],[987,1027,1028],{},"How many segments are too many?",[15,1030,1031],{},"When most segments have too few samples for a stable p75. A practical limit is two dimensions crossed at a time — device class by template, or connection by country — with a minimum of around a thousand page views per cell per reporting period. Beyond that, use segmentation to generate hypotheses and confirm them with targeted lab tests rather than ever-finer field slices.",[127,1033,1035],{"id":1034},"related","Related",[132,1037,1038,1045,1052],{},[135,1039,1040,1044],{},[19,1041,1043],{"href":1042},"\u002Fcore-web-vitals-measurement\u002Funderstanding-core-web-vitals-thresholds\u002Fpassing-desktop-but-failing-mobile-core-web-vitals\u002F","Passing desktop but failing mobile Core Web Vitals"," — the form-factor split in practice.",[135,1046,1047,1051],{},[19,1048,1050],{"href":1049},"\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fcomputing-p75-from-raw-rum-beacons\u002F","Computing p75 from raw RUM beacons"," — aggregating the segmented data correctly.",[135,1053,1054,1058],{},[19,1055,1057],{"href":1056},"\u002Fimage-media-optimization\u002Fimage-cdns-and-fetchpriority\u002Fusing-client-hints-for-image-width-and-dpr\u002F","Using Client Hints for image width and DPR"," — Client Hints applied to image delivery.",[1060,1061,1063],"script",{"type":1062},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Segment RUM Data by Device and Connection\",\n  \"description\": \"Which device and network dimensions to collect with RUM beacons, how to bucket them, and how to use them to explain a failing p75.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Collect device and network context once per page view\",\n      \"text\": \"Expected outcome: every beacon carries a handful of low-cardinality fields that cover device and network.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Derive a device class that works across browsers\",\n      \"text\": \"Combine signals into a small set of classes, with a fallback for browsers that expose less.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Use measured network timings for all browsers\",\n      \"text\": \"effectiveType and rtt are unavailable outside Chromium, but every browser exposes Navigation Timing.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Segment, then control for confounders\",\n      \"text\": \"Compute p75 per segment, and before drawing conclusions, check that the comparison holds within a template and within a country.\"\n    }\n  ]\n}\n",[1060,1065,1066],{"type":1062},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Segment RUM Data by Device and Connection\",\n  \"description\": \"Which device and network dimensions to collect with RUM beacons, how to bucket them, and how to use them to explain a failing p75.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection\u002F\"\n  }\n}\n",[1060,1068,1069],{"type":1062},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Core Web Vitals & Measurement\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"RUM Beacons & Field Data Collection\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Segmenting RUM by Device and Connection\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection\u002F\"\n    }\n  ]\n}\n",[1071,1072,1073],"style",{},"html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}",{"title":316,"searchDepth":337,"depth":337,"links":1075},[1076,1077,1078,1084,1085,1086,1087,1088],{"id":129,"depth":337,"text":130},{"id":177,"depth":337,"text":178},{"id":303,"depth":337,"text":304,"children":1079},[1080,1081,1082,1083],{"id":308,"depth":359,"text":309},{"id":602,"depth":359,"text":603},{"id":764,"depth":359,"text":765},{"id":783,"depth":359,"text":784},{"id":954,"depth":337,"text":955},{"id":961,"depth":337,"text":962},{"id":972,"depth":337,"text":973},{"id":979,"depth":337,"text":980},{"id":1034,"depth":337,"text":1035},"Which device and network dimensions to collect with RUM beacons, how to bucket them, and how to use them to explain a failing p75.","md",{"slug":1092,"type":1093,"breadcrumb":1094,"datePublished":1101,"dateModified":1101},"segmenting-rum-by-device-and-connection","article",[1095,1097,1098,1099],{"name":1096,"url":476},"Home",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1100},"\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection\u002F","2026-10-06",true,"\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection",{"title":1105,"description":1106},"Segmenting RUM Data by Device and Connection Class","Capture device memory, CPU cores, connection RTT and Client Hints with every beacon, then segment p75 to find which users fail Core Web Vitals and why.","core-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsegmenting-rum-by-device-and-connection\u002Findex","77BUiFLNQDPg6Fiy_LLneGyrQqac-fc6qvrafvjvXhY",[1110,1114],{"title":1111,"path":1112,"stem":1113},"Sampling RUM Data Without Biasing p75","\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsampling-rum-data-without-biasing-p75","core-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsampling-rum-data-without-biasing-p75\u002Findex",{"title":1115,"path":1116,"stem":1117},"Sending Web Vitals with sendBeacon on visibilitychange","\u002Fcore-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsending-web-vitals-with-sendbeacon-on-visibility-change","core-web-vitals-measurement\u002Frum-beacons-and-field-data-collection\u002Fsending-web-vitals-with-sendbeacon-on-visibility-change\u002Findex",1791308076822]