[{"data":1,"prerenderedAt":1233},["ShallowReactive",2],{"content:\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management":3,"surroundings:\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management":1224},{"id":4,"title":5,"body":6,"description":1204,"extension":1205,"meta":1206,"navigation":1217,"path":1218,"seo":1219,"stem":1222,"__hash__":1223},"content\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Findex.md","HTTP\u002F2, HTTP\u002F3 & Connection Management",{"type":7,"value":8,"toc":1183},"minimark",[9,14,24,36,39,189,194,210,213,217,234,238,428,432,442,446,449,453,456,509,630,634,640,654,660,670,674,680,686,703,709,715,719,728,779,783,789,793,799,872,876,895,899,918,922,925,931,935,962,966,998,1002,1014,1026,1035,1044,1053,1062,1071,1080,1089,1098,1107,1111,1141,1145,1168,1173,1176,1179],[10,11,13],"h1",{"id":12},"http2-http3-connection-management-fewer-faster-better-shared-connections","HTTP\u002F2, HTTP\u002F3 & Connection Management: Fewer, Faster, Better-Shared Connections",[15,16,17,18,23],"p",{},"This topic is part of ",[19,20,22],"a",{"href":21},"\u002Fnetwork-protocol-optimization\u002F","Network & Server Response Optimization",". Every resource a page loads travels over a connection, and connections are expensive to create: a DNS lookup, a TCP handshake, a TLS handshake, and a period of slow start while the congestion window grows. On a mobile network with a 150ms round-trip time, creating a new HTTPS connection over TCP takes 300–450ms before the first request can even be sent. How many connections a page needs, and how well they are used, has a large effect on loading speed.",[15,25,26,27,31,32,35],{},"HTTP\u002F1.1 allowed only one request at a time per connection, so browsers opened up to six connections per host, and developers invented workarounds: domain sharding (spreading assets across hostnames to get more connections), sprites and concatenation (fewer requests), inlining. ",[28,29,30],"strong",{},"HTTP\u002F2"," multiplexes many concurrent requests over one connection, with header compression and stream prioritisation, which makes most of those workarounds unnecessary and some harmful. ",[28,33,34],{},"HTTP\u002F3"," runs HTTP over QUIC, a UDP-based transport with built-in TLS 1.3: it needs fewer round trips to set up, avoids TCP's head-of-line blocking when packets are lost, and survives network changes such as moving from Wi-Fi to cellular.",[15,37,38],{},"Protocol upgrades are mostly configuration at the CDN or server. The bigger, ongoing work is connection management: limiting the number of distinct origins on the critical path, making sure connections are reused and coalesced, warming necessary connections early, and verifying in the field which protocols users actually get.",[15,40,41],{},[42,43,49,50,49,57,49,61,49,64,49,73,49,79,49,84,49,92,49,99,49,104,49,108,49,113,49,117,49,121,49,124,49,127,49,129,49,133,49,136,49,139,49,143,49,149,49,153,49,155,49,157,49,164,49,170,49,174,49,177,49,181,49,185,49],"svg",{"viewBox":44,"width":45,"role":46,"ariaLabel":47,"style":48},"0 0 760 216","100%","img","Timeline comparing time to the first request for HTTP\u002F2 over TLS 1.2, HTTP\u002F2 over TLS 1.3, and HTTP\u002F3.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[51,52],"rect",{"className":53,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],"svg-canvas","0","#ffffff",[58,59,60],"title",{},"Connection setup cost by protocol (150ms RTT)",[62,63,47],"desc",{},[51,65],{"x":66,"y":66,"width":67,"height":68,"rx":69,"fill":70,"stroke":71,"style":72},"1","758","214","10","none","currentColor","stroke-opacity:0.18",[74,75,60],"text",{"x":76,"y":77,"fill":71,"style":78},"28.0","34.0","font-size:16px;font-weight:700",[74,80,83],{"x":76,"y":81,"fill":71,"style":82},"74.0","font-size:12.5px;font-weight:700","H2 + TLS 1.2",[51,85],{"x":86,"y":87,"width":88,"height":89,"rx":90,"fill":71,"stroke":71,"style":91},"131.4","56.0","117.6","26.0","3","fill-opacity:0.06;stroke-opacity:0.4",[74,93,98],{"x":94,"y":95,"fill":71,"style":96,"textAnchor":97},"190.2","73.5","font-size:11.5px","middle","TCP",[51,100],{"x":101,"y":87,"width":102,"height":89,"rx":90,"fill":70,"stroke":71,"style":103},"250.4","236.6","stroke-opacity:0.35",[74,105,107],{"x":106,"y":95,"fill":71,"style":96,"textAnchor":97},"368.8","TLS 1.2 (2 RTT)",[51,109],{"x":110,"y":87,"width":88,"height":89,"rx":90,"fill":111,"stroke":111,"style":112},"488.6","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[74,114,116],{"x":115,"y":95,"fill":71,"style":96,"textAnchor":97},"547.4","request",[74,118,120],{"x":76,"y":119,"fill":71,"style":82},"112.0","H2 + TLS 1.3",[51,122],{"x":86,"y":123,"width":88,"height":89,"rx":90,"fill":71,"stroke":71,"style":91},"94.0",[74,125,98],{"x":94,"y":126,"fill":71,"style":96,"textAnchor":97},"111.5",[51,128],{"x":101,"y":123,"width":88,"height":89,"rx":90,"fill":71,"stroke":71,"style":91},[74,130,132],{"x":131,"y":126,"fill":71,"style":96,"textAnchor":97},"309.2","TLS 1.3",[51,134],{"x":135,"y":123,"width":88,"height":89,"rx":90,"fill":111,"stroke":111,"style":112},"369.5",[74,137,116],{"x":138,"y":126,"fill":71,"style":96,"textAnchor":97},"428.3",[74,140,142],{"x":76,"y":141,"fill":71,"style":82},"150.0","HTTP\u002F3 (QUIC)",[51,144],{"x":86,"y":145,"width":88,"height":89,"rx":90,"fill":146,"stroke":147,"style":148},"132.0","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[74,150,152],{"x":94,"y":151,"fill":71,"style":96,"textAnchor":97},"149.5","QUIC + TLS",[51,154],{"x":101,"y":145,"width":88,"height":89,"rx":90,"fill":111,"stroke":111,"style":112},[74,156,116],{"x":131,"y":151,"fill":71,"style":96,"textAnchor":97},[158,159],"line",{"x1":160,"y1":161,"x2":162,"y2":161,"stroke":71,"style":163},"130.6","172.0","726.0","stroke-opacity:0.4",[74,165,169],{"x":166,"y":167,"fill":168,"style":96,"textAnchor":97},"141.3","189.0","#51617a","0ms",[74,171,173],{"x":172,"y":167,"fill":168,"style":96,"textAnchor":97},"249.7","150ms",[74,175,176],{"x":106,"y":167,"fill":168,"style":96,"textAnchor":97},"300ms",[74,178,180],{"x":179,"y":167,"fill":168,"style":96,"textAnchor":97},"487.8","450ms",[74,182,184],{"x":183,"y":167,"fill":168,"style":96,"textAnchor":97},"606.9","600ms",[74,186,188],{"x":187,"y":167,"fill":168,"style":96,"textAnchor":97},"715.3","750ms",[190,191,193],"h2",{"id":192},"the-metric-degradation-this-topic-addresses","The Metric Degradation This Topic Addresses",[15,195,196,197,201,202,205,206,209],{},"Connection costs appear in TTFB (for the document's own connection), in resource load delay for critical subresources on other origins (fonts, CSS on a CDN domain, the LCP image on an image CDN), and in overall load time when many third-party origins are involved. In Navigation and Resource Timing, they show as ",[198,199,200],"code",{},"domainLookup",", ",[198,203,204],{},"connect"," and ",[198,207,208],{},"secureConnection"," durations; in waterfalls, as the coloured DNS\u002Fconnect\u002FTLS segments before a request starts.",[15,211,212],{},"Packet loss is the other factor. On TCP, a lost packet stalls every HTTP\u002F2 stream on that connection until it is retransmitted (transport head-of-line blocking). On lossy mobile networks this can make HTTP\u002F2 slower than several HTTP\u002F1.1 connections. HTTP\u002F3 avoids this because QUIC streams are independent.",[190,214,216],{"id":215},"prerequisites","Prerequisites",[218,219,220,228,231],"ul",{},[221,222,223,224,227],"li",{},"RUM data with ",[198,225,226],{},"nextHopProtocol"," and connection timing per resource (or at least for the navigation).",[221,229,230],{},"A list of origins contacted during page load, with which are on the critical path.",[221,232,233],{},"CDN and server configuration access to enable TLS 1.3 and HTTP\u002F3.",[190,235,237],{"id":236},"_1-environment-setup-inventory-origins-and-protocols","1. Environment Setup: Inventory Origins and Protocols",[239,240,245],"pre",{"className":241,"code":242,"language":243,"meta":244,"style":244},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Console: origins used during load, protocol, and connection time.\nconst byOrigin = {};\nfor (const r of performance.getEntriesByType('resource')) {\n  const o = new URL(r.name).origin;\n  const e = (byOrigin[o] ||= { count: 0, protocol: r.nextHopProtocol, connectMs: 0 });\n  e.count++;\n  e.connectMs = Math.max(e.connectMs, Math.round(r.connectEnd - r.domainLookupStart));\n}\nconsole.table(byOrigin);\n\u002F\u002F trade-off: cross-origin timing details are zero without Timing-Allow-Origin;\n\u002F\u002F the protocol is still reported for most resources.\n","javascript","",[198,246,247,255,273,307,327,356,368,398,404,416,422],{"__ignoreMap":244},[248,249,251],"span",{"class":158,"line":250},1,[248,252,254],{"class":253},"sjfSM","\u002F\u002F Console: origins used during load, protocol, and connection time.\n",[248,256,258,262,266,269],{"class":158,"line":257},2,[248,259,261],{"class":260},"sPARh","const",[248,263,265],{"class":264},"sPXB4"," byOrigin",[248,267,268],{"class":260}," =",[248,270,272],{"class":271},"saISM"," {};\n",[248,274,276,279,282,284,287,290,293,297,300,304],{"class":158,"line":275},3,[248,277,278],{"class":260},"for",[248,280,281],{"class":271}," (",[248,283,261],{"class":260},[248,285,286],{"class":264}," r",[248,288,289],{"class":260}," of",[248,291,292],{"class":271}," performance.",[248,294,296],{"class":295},"smZ65","getEntriesByType",[248,298,299],{"class":271},"(",[248,301,303],{"class":302},"sZ8jY","'resource'",[248,305,306],{"class":271},")) {\n",[248,308,310,313,316,318,321,324],{"class":158,"line":309},4,[248,311,312],{"class":260},"  const",[248,314,315],{"class":264}," o",[248,317,268],{"class":260},[248,319,320],{"class":260}," new",[248,322,323],{"class":295}," URL",[248,325,326],{"class":271},"(r.name).origin;\n",[248,328,330,332,335,337,340,343,346,348,351,353],{"class":158,"line":329},5,[248,331,312],{"class":260},[248,333,334],{"class":264}," e",[248,336,268],{"class":260},[248,338,339],{"class":271}," (byOrigin[o] ",[248,341,342],{"class":260},"||=",[248,344,345],{"class":271}," { count: ",[248,347,55],{"class":264},[248,349,350],{"class":271},", protocol: r.nextHopProtocol, connectMs: ",[248,352,55],{"class":264},[248,354,355],{"class":271}," });\n",[248,357,359,362,365],{"class":158,"line":358},6,[248,360,361],{"class":271},"  e.count",[248,363,364],{"class":260},"++",[248,366,367],{"class":271},";\n",[248,369,371,374,377,380,383,386,389,392,395],{"class":158,"line":370},7,[248,372,373],{"class":271},"  e.connectMs ",[248,375,376],{"class":260},"=",[248,378,379],{"class":271}," Math.",[248,381,382],{"class":295},"max",[248,384,385],{"class":271},"(e.connectMs, Math.",[248,387,388],{"class":295},"round",[248,390,391],{"class":271},"(r.connectEnd ",[248,393,394],{"class":260},"-",[248,396,397],{"class":271}," r.domainLookupStart));\n",[248,399,401],{"class":158,"line":400},8,[248,402,403],{"class":271},"}\n",[248,405,407,410,413],{"class":158,"line":406},9,[248,408,409],{"class":271},"console.",[248,411,412],{"class":295},"table",[248,414,415],{"class":271},"(byOrigin);\n",[248,417,419],{"class":158,"line":418},10,[248,420,421],{"class":253},"\u002F\u002F trade-off: cross-origin timing details are zero without Timing-Allow-Origin;\n",[248,423,425],{"class":158,"line":424},11,[248,426,427],{"class":253},"\u002F\u002F the protocol is still reported for most resources.\n",[190,429,431],{"id":430},"_2-capture-a-baseline","2. Capture a Baseline",[15,433,434,435,438,439,441],{},"Record the number of origins on the critical path (before LCP), connection times for each, the share of navigations and resources over ",[198,436,437],{},"h3"," versus ",[198,440,190],{},", and TTFB and LCP by protocol in the field.",[190,443,445],{"id":444},"_3-isolate-unnecessary-connections","3. Isolate Unnecessary Connections",[15,447,448],{},"Classify each origin: needed early (critical CSS, fonts, LCP image), needed later (analytics, chat), or avoidable (sharded asset domains, a separate domain for a single small file). Check whether multiple hostnames could share a connection via coalescing.",[190,450,452],{"id":451},"_4-apply-consolidate-upgrade-warm","4. Apply: Consolidate, Upgrade, Warm",[15,454,455],{},"Consolidate critical resources onto the main origin or one CDN hostname. Enable TLS 1.3 and HTTP\u002F3. Remove domain sharding. Preconnect to the few remaining critical third-party origins. Defer non-critical third parties until after load.",[239,457,461],{"className":458,"code":459,"language":460,"meta":244,"style":244},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003C!-- Warm the one critical third-party origin; self-host the rest. -->\n\u003Clink rel=\"preconnect\" href=\"https:\u002F\u002Fimages.example-cdn.com\" crossorigin>\n\u003C!-- trade-off: each preconnect opens a socket and does TLS work even if the\n     origin is not used soon; limit preconnects to two or three critical origins. -->\n","html",[198,462,463,468,499,504],{"__ignoreMap":244},[248,464,465],{"class":158,"line":250},[248,466,467],{"class":253},"\u003C!-- Warm the one critical third-party origin; self-host the rest. -->\n",[248,469,470,473,477,480,482,485,488,490,493,496],{"class":158,"line":257},[248,471,472],{"class":271},"\u003C",[248,474,476],{"class":475},"sZBmE","link",[248,478,479],{"class":264}," rel",[248,481,376],{"class":271},[248,483,484],{"class":302},"\"preconnect\"",[248,486,487],{"class":264}," href",[248,489,376],{"class":271},[248,491,492],{"class":302},"\"https:\u002F\u002Fimages.example-cdn.com\"",[248,494,495],{"class":264}," crossorigin",[248,497,498],{"class":271},">\n",[248,500,501],{"class":158,"line":275},[248,502,503],{"class":253},"\u003C!-- trade-off: each preconnect opens a socket and does TLS work even if the\n",[248,505,506],{"class":158,"line":309},[248,507,508],{"class":253},"     origin is not used soon; limit preconnects to two or three critical origins. -->\n",[15,510,511],{},[42,512,49,515,49,518,49,521,49,523,49,540,49,543,49,545,49,550,49,555,49,560,49,563,49,567,49,570,49,573,49,577,49,580,49,583,49,587,49,591,49,593,49,596,49,599,49,601,49,604,49,607,49,615,49,619,49,623,49,627,49],{"viewBox":513,"width":45,"role":46,"ariaLabel":514,"style":48},"0 0 760 232","Workflow from inventorying origins and protocols to consolidating, upgrading and warming connections.",[51,516],{"className":517,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,519,520],{},"Connection management workflow",[62,522,514],{},[524,525,526],"defs",{},[527,528,535],"marker",{"id":529,"viewBox":530,"refX":531,"refY":532,"markerWidth":533,"markerHeight":533,"orient":534},"fa5591aa1d","0 0 10 10","9","5","7","auto-start-reverse",[536,537],"path",{"d":538,"fill":71,"style":539},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[51,541],{"x":66,"y":66,"width":67,"height":542,"rx":69,"fill":70,"stroke":71,"style":72},"230",[74,544,520],{"x":76,"y":77,"fill":71,"style":78},[51,546],{"x":76,"y":87,"width":547,"height":548,"rx":549,"fill":111,"stroke":111,"style":112},"208.0","55.0","6",[74,551,554],{"x":145,"y":552,"fill":71,"style":553,"textAnchor":97},"78.0","font-size:13px;font-weight:700","Inventory",[74,556,559],{"x":145,"y":557,"fill":71,"style":558,"textAnchor":97},"96.0","font-size:12px","origins + protocol",[51,561],{"x":562,"y":87,"width":547,"height":548,"rx":549,"fill":111,"stroke":111,"style":112},"276.0",[74,564,566],{"x":565,"y":552,"fill":71,"style":553,"textAnchor":97},"380.0","Classify",[74,568,569],{"x":565,"y":557,"fill":71,"style":558,"textAnchor":97},"critical vs later",[51,571],{"x":572,"y":87,"width":547,"height":548,"rx":549,"fill":146,"stroke":147,"style":148},"524.0",[74,574,576],{"x":575,"y":552,"fill":71,"style":553,"textAnchor":97},"628.0","Consolidate",[74,578,579],{"x":575,"y":557,"fill":71,"style":558,"textAnchor":97},"fewer origins",[51,581],{"x":572,"y":582,"width":547,"height":548,"rx":549,"fill":146,"stroke":147,"style":148},"155.0",[74,584,586],{"x":575,"y":585,"fill":71,"style":553,"textAnchor":97},"177.0","Upgrade",[74,588,590],{"x":575,"y":589,"fill":71,"style":558,"textAnchor":97},"195.0","TLS 1.3 + HTTP\u002F3",[51,592],{"x":562,"y":582,"width":547,"height":548,"rx":549,"fill":111,"stroke":111,"style":112},[74,594,595],{"x":565,"y":585,"fill":71,"style":553,"textAnchor":97},"Warm",[74,597,598],{"x":565,"y":589,"fill":71,"style":558,"textAnchor":97},"preconnect critical",[51,600],{"x":76,"y":582,"width":547,"height":548,"rx":549,"fill":111,"stroke":111,"style":112},[74,602,603],{"x":145,"y":585,"fill":71,"style":553,"textAnchor":97},"Verify",[74,605,606],{"x":145,"y":589,"fill":71,"style":558,"textAnchor":97},"h3 share, LCP by protocol",[158,608],{"x1":609,"y1":610,"x2":611,"y2":610,"stroke":71,"strokeWidth":612,"style":613,"markerEnd":614},"236.0","83.5","274.0","1.5","stroke-opacity:0.6","url(#fa5591aa1d)",[158,616],{"x1":617,"y1":610,"x2":618,"y2":610,"stroke":71,"strokeWidth":612,"style":613,"markerEnd":614},"484.0","522.0",[158,620],{"x1":575,"y1":621,"x2":575,"y2":622,"stroke":71,"strokeWidth":612,"style":613,"markerEnd":614},"111.0","153.0",[158,624],{"x1":572,"y1":625,"x2":626,"y2":625,"stroke":71,"strokeWidth":612,"style":613,"markerEnd":614},"182.5","486.0",[158,628],{"x1":562,"y1":625,"x2":629,"y2":625,"stroke":71,"strokeWidth":612,"style":613,"markerEnd":614},"238.0",[190,631,633],{"id":632},"deconstructing-http2-and-http3-behaviour","Deconstructing HTTP\u002F2 and HTTP\u002F3 Behaviour",[15,635,636,639],{},[28,637,638],{},"Multiplexing."," HTTP\u002F2 and HTTP\u002F3 send many requests concurrently over one connection, interleaving response frames. This removes the HTTP\u002F1.1 per-connection request queue, so many small files are no longer expensive — although each request still has some overhead, and very large numbers of tiny files remain less efficient than moderately bundled ones.",[15,641,642,645,646,649,650,653],{},[28,643,644],{},"Prioritisation."," With many requests on one connection, the server decides which responses to send first. Browsers signal priorities (render-blocking CSS and the LCP image high, async scripts and lazy images low), and the ",[198,647,648],{},"fetchpriority"," attribute adjusts them. HTTP\u002F2's original dependency-tree priority scheme was implemented inconsistently by servers; the newer Extensible Priorities scheme (",[198,651,652],{},"Priority"," header, urgency and incremental flags) is used by HTTP\u002F3 and modern HTTP\u002F2 implementations. Poor server prioritisation can delay critical resources behind large, unimportant ones.",[15,655,656,659],{},[28,657,658],{},"Connection reuse and coalescing."," Browsers reuse an open connection for further requests to the same origin. They can also coalesce: if a new hostname resolves to the same IP as an existing connection and the certificate covers both names, the browser can send requests for both over one connection. This makes separate asset subdomains nearly free — if configured correctly.",[15,661,662,665,666,669],{},[28,663,664],{},"HTTP\u002F3 discovery."," Browsers learn that a server supports HTTP\u002F3 from the ",[198,667,668],{},"Alt-Svc"," response header (or from DNS HTTPS records). The first visit typically uses HTTP\u002F2; subsequent connections may use HTTP\u002F3. DNS HTTPS records allow HTTP\u002F3 on the first connection.",[190,671,673],{"id":672},"advanced-diagnostics-and-edge-cases","Advanced Diagnostics and Edge Cases",[15,675,676,679],{},[28,677,678],{},"UDP blocked."," Some corporate networks block UDP 443; browsers fall back to HTTP\u002F2. Expect a share of users to never use HTTP\u002F3.",[15,681,682,685],{},[28,683,684],{},"Connection limits and slow start."," A single new connection starts with a small congestion window; large early responses take several round trips to ramp up. Reusing warm connections avoids slow start.",[15,687,688,691,692,695,696,699,700,702],{},[28,689,690],{},"Credentialed vs anonymous connections."," Browsers keep separate connection pools for requests with and without credentials. Fonts and ",[198,693,694],{},"crossorigin"," resources use anonymous connections, so ",[198,697,698],{},"preconnect"," needs ",[198,701,694],{}," to warm the right pool.",[15,704,705,708],{},[28,706,707],{},"Third-party origins."," Each adds DNS, connection and TLS cost, plus prioritisation that your server cannot control. Self-hosting critical third-party resources (fonts, key scripts) often helps more than any protocol setting.",[15,710,711,714],{},[28,712,713],{},"Server push."," HTTP\u002F2 server push has been removed from browsers. Use 103 Early Hints with preload instead.",[190,716,718],{"id":717},"validation-and-budgeting","Validation and Budgeting",[15,720,721,722,724,725,727],{},"Validate protocol adoption with ",[198,723,226],{}," in RUM: the share of navigations over ",[198,726,437],{}," should rise after enabling HTTP\u002F3, typically to a majority for repeat visitors on mobile. Compare TTFB and LCP by protocol and by connection type. Budget the number of origins contacted before LCP.",[412,729,730,743],{},[731,732,733],"thead",{},[734,735,736,740],"tr",{},[737,738,739],"th",{},"Budget",[737,741,742],{},"Target",[744,745,746,755,763,771],"tbody",{},[734,747,748,752],{},[749,750,751],"td",{},"Origins before LCP",[749,753,754],{},"≤ 3",[734,756,757,760],{},[749,758,759],{},"TLS version",[749,761,762],{},"1.3 everywhere",[734,764,765,768],{},[749,766,767],{},"HTTP\u002F3 enabled at CDN",[749,769,770],{},"Yes, with Alt-Svc or HTTPS DNS record",[734,772,773,776],{},[749,774,775],{},"Preconnect hints",[749,777,778],{},"≤ 3, all used within 10 seconds",[190,780,782],{"id":781},"worked-example-a-travel-booking-site","Worked Example: A Travel Booking Site",[15,784,785,786,788],{},"A travel site's homepage contacted 14 origins before LCP: the main site, a static asset domain, an image CDN, three font origins, a tag manager, an A\u002FB testing service and several ad-tech domains. Connection setup for critical origins added 400–700ms on mobile. The team served static assets and fonts from the main origin (via the CDN), kept the image CDN with a preconnect, deferred the tag manager and A\u002FB script until after LCP (moving experiments to the edge), and enabled HTTP\u002F3 and TLS 1.3 at the CDN. Origins before LCP fell to three, ",[198,787,437],{}," share reached 64% of navigations, and LCP p75 on mobile improved from 3.3 seconds to 2.4 seconds. The protocol upgrade alone accounted for about 120ms; consolidating origins for most of the rest.",[190,790,792],{"id":791},"measuring-protocol-gains-honestly","Measuring Protocol Gains Honestly",[15,794,795,796,798],{},"HTTP\u002F3 improvements are real but uneven. Users on fast, stable connections see little difference; users on high-latency or lossy networks see the most. Averaged across all users, gains can look small and be mistaken for noise. Segment field data by protocol and by network quality (effective connection type, round-trip time from Network Information API where available, or country) to see where gains concentrate. Be careful with selection bias: users who get HTTP\u002F3 are disproportionately repeat visitors with a known ",[198,797,668],{},", who also have warmer caches. Comparing before and after enabling HTTP\u002F3 for the same population is more reliable than comparing h2 and h3 users in the same period.",[15,800,801],{},[42,802,49,805,49,808,49,811,49,813,49,816,49,818,49,825,49,831,49,836,49,840,49,844,49,848,49,851,49,856,49,860,49,864,49,868,49],{"viewBox":803,"width":45,"role":46,"ariaLabel":804,"style":48},"0 0 760 194","Bar chart showing how much LCP p75 improved after enabling HTTP\u002F3 for users on different network conditions.",[51,806],{"className":807,"x":55,"y":55,"width":45,"height":45,"fill":56},[54],[58,809,810],{},"LCP p75 improvement after enabling HTTP\u002F3, by network",[62,812,804],{},[51,814],{"x":66,"y":66,"width":67,"height":815,"rx":69,"fill":70,"stroke":71,"style":72},"192",[74,817,810],{"x":76,"y":77,"fill":71,"style":78},[74,819,824],{"x":820,"y":821,"fill":71,"style":822,"textAnchor":823},"206.6","70.0","font-size:13px","end","Fast broadband",[51,826],{"x":827,"y":87,"width":828,"height":829,"rx":90,"fill":111,"stroke":111,"style":830},"218.6","23.7","19","fill-opacity:0.55;stroke-opacity:0.9",[74,832,835],{"x":833,"y":821,"fill":71,"style":834},"248.2","font-size:12px;font-weight:600","20ms",[74,837,839],{"x":820,"y":838,"fill":71,"style":822,"textAnchor":823},"101.0","4G urban",[51,841],{"x":827,"y":842,"width":843,"height":829,"rx":90,"fill":111,"stroke":111,"style":830},"87.0","106.4",[74,845,847],{"x":846,"y":838,"fill":71,"style":834},"331.0","90ms",[74,849,850],{"x":820,"y":145,"fill":71,"style":822,"textAnchor":823},"4G rural \u002F high RTT",[51,852],{"x":827,"y":853,"width":854,"height":829,"rx":90,"fill":146,"stroke":147,"style":855},"118.0","283.8","fill-opacity:0.7;stroke-opacity:0.9",[74,857,859],{"x":858,"y":145,"fill":71,"style":834},"508.4","240ms",[74,861,863],{"x":820,"y":862,"fill":71,"style":822,"textAnchor":823},"163.0","Lossy networks (over 2% loss)",[51,865],{"x":827,"y":866,"width":867,"height":829,"rx":90,"fill":146,"stroke":147,"style":855},"149.0","449.4",[74,869,871],{"x":870,"y":862,"fill":71,"style":834},"674.0","380ms",[190,873,875],{"id":874},"legacy-http11-optimizations-to-undo","Legacy HTTP\u002F1.1 Optimizations to Undo",[15,877,878,879,882,883,886,887,890,891,894],{},"Several techniques from the HTTP\u002F1.1 era are counterproductive now. ",[28,880,881],{},"Domain sharding"," adds connections that must each be set up and that compete for bandwidth without coordinated prioritisation. ",[28,884,885],{},"Excessive concatenation"," into one giant bundle defeats caching (any change invalidates everything) and delays execution until the whole file arrives. ",[28,888,889],{},"Image sprites"," force downloading every icon to show one. ",[28,892,893],{},"Inlining large assets"," as data URIs bloats HTML and CSS and prevents separate caching. Each made sense when requests were expensive; with multiplexing, a moderate number of well-cached files usually performs better.",[190,896,898],{"id":897},"early-hints-and-connection-warmup","Early Hints and Connection Warmup",[15,900,901,902,905,906,909,910,913,914,917],{},"When the server needs time to generate the HTML, it can send a ",[198,903,904],{},"103 Early Hints"," response immediately with ",[198,907,908],{},"Link"," headers for critical resources (",[198,911,912],{},"rel=preload"," for CSS, fonts and the LCP image, ",[198,915,916],{},"rel=preconnect"," for critical origins). The browser starts connecting and downloading during the server's think time. Early Hints work over HTTP\u002F2 and HTTP\u002F3 and are supported by major CDNs, which can cache and replay hints for each URL. They are the modern replacement for server push, with the advantage that the browser decides whether it needs each resource.",[190,919,921],{"id":920},"third-party-origins-and-the-critical-path","Third-Party Origins and the Critical Path",[15,923,924],{},"Most of the connections a typical page opens are to third parties: analytics, tag managers, consent platforms, A\u002FB testing, chat, ads, social embeds, font services. Each is a separate origin with its own connection setup, and none can be coalesced with yours. When any of them sits on the critical path — a synchronous script in the head, a font stylesheet, an anti-flicker snippet — its connection cost adds directly to FCP and LCP.",[15,926,927,928,930],{},"Audit third parties by when they are needed. Fonts and critical CSS should be self-hosted so they share the main connection. Experimentation and personalisation can often move to the edge or server, removing the client-side script from the critical path. Analytics, chat and marketing tags can load after the page is interactive. For the few third-party origins that must load early, a ",[198,929,698],{}," hint starts the connection in parallel with the HTML. The goal is a critical path that touches one or two origins, with everything else arriving later on connections that do not delay rendering.",[190,932,934],{"id":933},"a-rollout-plan","A Rollout Plan",[936,937,938,941,944,947,950,953,956],"ol",{},[221,939,940],{},"Inventory origins and protocols on key templates.",[221,942,943],{},"Enable TLS 1.3 and HTTP\u002F3 at the CDN; add HTTPS DNS records if supported.",[221,945,946],{},"Remove domain sharding and consolidate critical assets onto one origin.",[221,948,949],{},"Self-host critical third-party resources such as fonts.",[221,951,952],{},"Preconnect only to remaining critical origins; defer non-critical third parties.",[221,954,955],{},"Add Early Hints for pages with significant server think time.",[221,957,958,959,961],{},"Track ",[198,960,226],{},", origins before LCP, and LCP by protocol in RUM.",[190,963,965],{"id":964},"common-pitfalls","Common Pitfalls",[218,967,968,974,980,986,992],{},[221,969,970,973],{},[28,971,972],{},"Domain sharding on HTTP\u002F2."," More connections, worse prioritisation.",[221,975,976,979],{},[28,977,978],{},"Too many preconnects."," Wasted sockets and CPU, and contention with critical work.",[221,981,982,985],{},[28,983,984],{},"Missing crossorigin on preconnect for fonts."," Warms the wrong connection pool.",[221,987,988,991],{},[28,989,990],{},"Assuming HTTP\u002F3 for everyone."," UDP blocking and first visits still use HTTP\u002F2.",[221,993,994,997],{},[28,995,996],{},"Relying on server push."," Removed from browsers; use Early Hints.",[190,999,1001],{"id":1000},"faq","FAQ",[1003,1004,1007,1011],"details",{"className":1005},[1006],"faq-item",[1008,1009,1010],"summary",{},"Is HTTP\u002F3 faster than HTTP\u002F2?",[15,1012,1013],{},"On high-latency or lossy networks, usually yes, thanks to faster setup and no transport head-of-line blocking. On fast, stable networks, the difference is small.",[1003,1015,1017,1020],{"className":1016},[1006],[1008,1018,1019],{},"How do I enable HTTP\u002F3?",[15,1021,1022,1023,1025],{},"Most CDNs offer a setting to enable it. Self-hosted servers need QUIC support (for example nginx with HTTP\u002F3, or Caddy) and UDP port 443 open, plus an ",[198,1024,668],{}," header.",[1003,1027,1029,1032],{"className":1028},[1006],[1008,1030,1031],{},"Should I still bundle JavaScript with HTTP\u002F2?",[15,1033,1034],{},"Yes, moderately. Many tiny modules have overhead even with multiplexing. Aim for sensible chunks — per route and shared vendor chunks — rather than one huge bundle or hundreds of tiny files.",[1003,1036,1038,1041],{"className":1037},[1006],[1008,1039,1040],{},"Does HTTP\u002F2 make domain sharding obsolete?",[15,1042,1043],{},"Yes. Sharding adds connection costs and splits prioritisation; consolidate onto as few origins as possible.",[1003,1045,1047,1050],{"className":1046},[1006],[1008,1048,1049],{},"What is connection coalescing?",[15,1051,1052],{},"Reusing one HTTP\u002F2 or HTTP\u002F3 connection for several hostnames when they resolve to the same IP and the certificate covers all of them.",[1003,1054,1056,1059],{"className":1055},[1006],[1008,1057,1058],{},"How many preconnects should I use?",[15,1060,1061],{},"Two or three at most, for origins needed in the first seconds. More can compete with critical requests.",[1003,1063,1065,1068],{"className":1064},[1006],[1008,1066,1067],{},"Why do some users never get HTTP\u002F3?",[15,1069,1070],{},"UDP may be blocked on their network, their browser may not have learned about HTTP\u002F3 support yet, or their middleboxes interfere. Browsers fall back to HTTP\u002F2 automatically.",[1003,1072,1074,1077],{"className":1073},[1006],[1008,1075,1076],{},"Does HTTP\u002F2 prioritisation work reliably?",[15,1078,1079],{},"It depends on the server or CDN. Modern CDNs generally implement Extensible Priorities well; some self-hosted servers and proxies historically did not. Check waterfalls to see whether critical resources finish before large images.",[1003,1081,1083,1086],{"className":1082},[1006],[1008,1084,1085],{},"Do connection costs matter on desktop broadband?",[15,1087,1088],{},"Less, because round trips are short. They matter most on mobile networks, where each round trip can take 100–300ms and several connections add up to a second or more.",[1003,1090,1092,1095],{"className":1091},[1006],[1008,1093,1094],{},"Should I use Early Hints?",[15,1096,1097],{},"If your HTML takes noticeable time to generate and your CDN supports 103 responses, yes — they let the browser start critical downloads and connections during server think time.",[1003,1099,1101,1104],{"className":1100},[1006],[1008,1102,1103],{},"Is TLS 1.3 required for HTTP\u002F3?",[15,1105,1106],{},"Yes. QUIC integrates TLS 1.3 into its handshake, which is part of why HTTP\u002F3 needs fewer round trips to establish a secure connection.",[190,1108,1110],{"id":1109},"guides-in-this-topic","Guides in This Topic",[218,1112,1113,1120,1127,1134],{},[221,1114,1115,1119],{},[19,1116,1118],{"href":1117},"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fmeasuring-real-world-http3-gains\u002F","Measuring real-world HTTP\u002F3 gains"," — field measurement by protocol.",[221,1121,1122,1126],{},[19,1123,1125],{"href":1124},"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fwhy-domain-sharding-hurts-on-http2\u002F","Why domain sharding hurts on HTTP\u002F2"," — undoing a legacy optimization.",[221,1128,1129,1133],{},[19,1130,1132],{"href":1131},"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fconnection-coalescing-and-certificates\u002F","Connection coalescing and certificates"," — sharing connections across hostnames.",[221,1135,1136,1140],{},[19,1137,1139],{"href":1138},"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fdiagnosing-head-of-line-blocking\u002F","Diagnosing head-of-line blocking"," — when one stream stalls the rest.",[190,1142,1144],{"id":1143},"related","Related",[218,1146,1147,1154,1161],{},[221,1148,1149,1153],{},[19,1150,1152],{"href":1151},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fresource-hints-and-early-hints\u002Fdns-prefetch-vs-preconnect\u002F","DNS prefetch vs preconnect"," — warming connections.",[221,1155,1156,1160],{},[19,1157,1159],{"href":1158},"\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002F","Time to First Byte (TTFB) optimization"," — connection time in TTFB.",[221,1162,1163,1167],{},[19,1164,1166],{"href":1165},"\u002Fimage-media-optimization\u002Fimage-cdns-and-fetchpriority\u002Fusing-fetchpriority-to-prioritize-the-lcp-image\u002F","Using fetchpriority to prioritize the LCP image"," — prioritisation over multiplexed connections.",[1169,1170,1172],"script",{"type":1171},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"HTTP\u002F2, HTTP\u002F3 & Connection Management: Fewer, Faster, Better-Shared Connections\",\n  \"description\": \"How HTTP\u002F2 and HTTP\u002F3 change connection costs, which old optimizations now hurt, and how to manage origins and connections for faster loading.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Environment Setup: Inventory Origins and Protocols\",\n      \"text\": \"Environment Setup: Inventory Origins and Protocols\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Capture a Baseline\",\n      \"text\": \"Record the number of origins on the critical path (before LCP), connection times for each, the share of navigations and resources over h3 versus h2, and TTFB and LCP by protocol in the field.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Isolate Unnecessary Connections\",\n      \"text\": \"Classify each origin: needed early (critical CSS, fonts, LCP image), needed later (analytics, chat), or avoidable (sharded asset domains, a separate domain for a single small file).\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Apply: Consolidate, Upgrade, Warm\",\n      \"text\": \"Consolidate critical resources onto the main origin or one CDN hostname.\"\n    }\n  ]\n}\n",[1169,1174,1175],{"type":1171},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"HTTP\u002F2, HTTP\u002F3 & Connection Management: Fewer, Faster, Better-Shared Connections\",\n  \"description\": \"How HTTP\u002F2 and HTTP\u002F3 change connection costs, which old optimizations now hurt, and how to manage origins and connections for faster loading.\",\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\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002F\"\n  }\n}\n",[1169,1177,1178],{"type":1171},"\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\": \"Network & Server Response Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"HTTP\u002F2, HTTP\u002F3 & Connection Management\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002F\"\n    }\n  ]\n}\n",[1180,1181,1182],"style",{},"html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}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 .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}",{"title":244,"searchDepth":257,"depth":257,"links":1184},[1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203],{"id":192,"depth":257,"text":193},{"id":215,"depth":257,"text":216},{"id":236,"depth":257,"text":237},{"id":430,"depth":257,"text":431},{"id":444,"depth":257,"text":445},{"id":451,"depth":257,"text":452},{"id":632,"depth":257,"text":633},{"id":672,"depth":257,"text":673},{"id":717,"depth":257,"text":718},{"id":781,"depth":257,"text":782},{"id":791,"depth":257,"text":792},{"id":874,"depth":257,"text":875},{"id":897,"depth":257,"text":898},{"id":920,"depth":257,"text":921},{"id":933,"depth":257,"text":934},{"id":964,"depth":257,"text":965},{"id":1000,"depth":257,"text":1001},{"id":1109,"depth":257,"text":1110},{"id":1143,"depth":257,"text":1144},"How HTTP\u002F2 and HTTP\u002F3 change connection costs, which old optimizations now hurt, and how to manage origins and connections for faster loading.","md",{"slug":1207,"type":1208,"breadcrumb":1209,"datePublished":1216,"dateModified":1216},"http2-http3-and-connection-management","topic",[1210,1213,1214],{"name":1211,"url":1212},"Home","\u002F",{"name":22,"url":21},{"name":5,"url":1215},"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002F","2026-10-06",true,"\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management",{"title":1220,"description":1221},"HTTP\u002F2, HTTP\u002F3 and Connection Management for Speed","Use HTTP\u002F2 multiplexing and HTTP\u002F3 over QUIC well: fewer origins, connection reuse and coalescing, prioritisation, and measuring protocol gains in the field.","network-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Findex","CwhXkA4NPyJMVMGJnxEyPBlwzADJJqrq0EoX9AWpSMM",[1225,1229],{"title":1226,"path":1227,"stem":1228,"children":-1},"Zstandard Content-Encoding for the Web","\u002Fnetwork-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fzstandard-content-encoding-for-the-web","network-protocol-optimization\u002Fcompression-brotli-and-zstandard\u002Fzstandard-content-encoding-for-the-web\u002Findex",{"title":1230,"path":1231,"stem":1232,"children":-1},"Connection Coalescing and Certificates","\u002Fnetwork-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fconnection-coalescing-and-certificates","network-protocol-optimization\u002Fhttp2-http3-and-connection-management\u002Fconnection-coalescing-and-certificates\u002Findex",1791308070229]