[{"data":1,"prerenderedAt":1011},["ShallowReactive",2],{"content:\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts":3,"surroundings:\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts":1002},{"id":4,"title":5,"body":6,"description":980,"extension":981,"meta":982,"navigation":995,"path":996,"seo":997,"stem":1000,"__hash__":1001},"content\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts\u002Findex.md","Fixing TTFB from Serverless Cold Starts",{"type":7,"value":8,"toc":963},"minimark",[9,14,34,37,183,188,221,225,231,237,243,249,253,258,509,513,516,520,523,527,530,605,609,616,620,627,759,763,766,770,796,800,806,812,818,824,828,840,849,858,867,876,885,894,903,912,921,925,948,953,956,959],[10,11,13],"h1",{"id":12},"how-to-fix-ttfb-from-serverless-cold-starts","How to Fix TTFB from Serverless Cold Starts",[15,16,17,18,23,24,28,29,33],"p",{},"This guide is part of ",[19,20,22],"a",{"href":21},"\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002F","Time to First Byte Optimization",", within ",[19,25,27],{"href":26},"\u002Fnetwork-protocol-optimization\u002F","Network & Server Response Optimization",". Serverless functions — AWS Lambda, Google Cloud Run functions, Azure Functions, and the server rendering functions behind Vercel and Netlify deployments — scale by creating new instances on demand. A new instance must start a runtime, load your code, and run initialisation (importing modules, creating clients, connecting to databases) before it can handle the request. This ",[30,31,32],"strong",{},"cold start"," can add 200ms to several seconds to TTFB.",[15,35,36],{},"For high-traffic routes, most requests hit warm instances and cold starts are rare. But low-traffic pages, traffic spikes, new deployments and regions with little traffic see many cold starts, and they show up as a long tail in TTFB: p75 looks acceptable, p90 and p95 do not. On sites where every page is rendered by functions, cold starts can be the main reason for poor field LCP.",[15,38,39],{},[40,41,47,48,47,55,47,59,47,62,47,71,47,77,47,82,47,92,47,99,47,103,47,108,47,113,47,118,47,122,47,126,47,130,47,135,47,138,47,145,47,151,47,155,47,159,47,163,47,167,47,171,47,175,47,179,47],"svg",{"viewBox":42,"width":43,"role":44,"ariaLabel":45,"style":46},"0 0 760 178","100%","img","Timeline comparing TTFB for a warm function invocation with a cold start that includes runtime start, code loading and initialisation.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[49,50],"rect",{"className":51,"x":53,"y":53,"width":43,"height":43,"fill":54},[52],"svg-canvas","0","#ffffff",[56,57,58],"title",{},"Cold vs warm serverless request",[60,61,45],"desc",{},[49,63],{"x":64,"y":64,"width":65,"height":66,"rx":67,"fill":68,"stroke":69,"style":70},"1","758","176","10","none","currentColor","stroke-opacity:0.18",[72,73,58],"text",{"x":74,"y":75,"fill":69,"style":76},"28.0","34.0","font-size:16px;font-weight:700",[72,78,81],{"x":74,"y":79,"fill":69,"style":80},"74.0","font-size:12.5px;font-weight:700","Warm",[49,83],{"x":84,"y":85,"width":86,"height":87,"rx":88,"fill":89,"stroke":90,"style":91},"78.1","56.0","71.5","26.0","3","#ffc300","#b8860b","fill-opacity:0.24;stroke-opacity:0.9",[72,93,98],{"x":94,"y":95,"fill":69,"style":96,"textAnchor":97},"113.8","73.5","font-size:11.5px","middle","handler",[72,100,102],{"x":74,"y":101,"fill":69,"style":80},"112.0","Cold",[49,104],{"x":84,"y":105,"width":106,"height":87,"rx":88,"fill":69,"stroke":69,"style":107},"94.0","99.9","fill-opacity:0.06;stroke-opacity:0.4",[72,109,112],{"x":110,"y":111,"fill":69,"style":96,"textAnchor":97},"128.0","111.5","runtime start",[49,114],{"x":115,"y":105,"width":116,"height":87,"rx":88,"fill":68,"stroke":69,"style":117},"179.4","201.2","stroke-opacity:0.35",[72,119,121],{"x":120,"y":111,"fill":69,"style":96,"textAnchor":97},"280.0","load 6MB bundle",[49,123],{"x":124,"y":105,"width":125,"height":87,"rx":88,"fill":68,"stroke":69,"style":117},"382.1","160.7",[72,127,129],{"x":128,"y":111,"fill":69,"style":96,"textAnchor":97},"462.5","init + DB connect",[49,131],{"x":132,"y":105,"width":86,"height":87,"rx":88,"fill":133,"stroke":133,"style":134},"544.3","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[72,136,98],{"x":137,"y":111,"fill":69,"style":96,"textAnchor":97},"580.1",[139,140],"line",{"x1":141,"y1":142,"x2":143,"y2":142,"stroke":69,"style":144},"77.3","134.0","726.0","stroke-opacity:0.4",[72,146,150],{"x":147,"y":148,"fill":149,"style":96,"textAnchor":97},"88.0","151.0","#51617a","0ms",[72,152,154],{"x":153,"y":148,"fill":149,"style":96,"textAnchor":97},"158.4","200ms",[72,156,158],{"x":157,"y":148,"fill":149,"style":96,"textAnchor":97},"239.5","400ms",[72,160,162],{"x":161,"y":148,"fill":149,"style":96,"textAnchor":97},"320.6","600ms",[72,164,166],{"x":165,"y":148,"fill":149,"style":96,"textAnchor":97},"401.7","800ms",[72,168,170],{"x":169,"y":148,"fill":149,"style":96,"textAnchor":97},"482.8","1000ms",[72,172,174],{"x":173,"y":148,"fill":149,"style":96,"textAnchor":97},"563.8","1200ms",[72,176,178],{"x":177,"y":148,"fill":149,"style":96,"textAnchor":97},"644.9","1400ms",[72,180,182],{"x":181,"y":148,"fill":149,"style":96,"textAnchor":97},"712.3","1600ms",[184,185,187],"h2",{"id":186},"rapid-diagnosis","Rapid Diagnosis",[189,190,191,198,204,215],"ul",{},[192,193,194,197],"li",{},[30,195,196],{},"Report init time"," as a Server-Timing entry (or log it) to identify cold requests.",[192,199,200,203],{},[30,201,202],{},"Compare TTFB distributions",": a long tail at p90+ with a fast median suggests cold starts.",[192,205,206,209,210,214],{},[30,207,208],{},"Check platform metrics",": Lambda's ",[211,212,213],"code",{},"Init Duration"," in logs, or equivalent on other platforms.",[192,216,217,220],{},[30,218,219],{},"Check function bundle size",": large bundles take longer to load.",[184,222,224],{"id":223},"root-cause-analysis","Root Cause Analysis",[15,226,227,230],{},[30,228,229],{},"1. Large bundles."," Loading and parsing megabytes of JavaScript at startup.",[15,232,233,236],{},[30,234,235],{},"2. Heavy initialisation."," Creating SDK clients, loading configuration, warming caches on startup.",[15,238,239,242],{},[30,240,241],{},"3. Database connections."," New TCP and TLS connections from each new instance, sometimes with connection limits.",[15,244,245,248],{},[30,246,247],{},"4. Low or spiky traffic."," More requests land on new instances.",[184,250,252],{"id":251},"step-by-step-resolution","Step-by-Step Resolution",[254,255,257],"h3",{"id":256},"_1-measure-cold-start-share-and-cost","1. Measure cold start share and cost",[259,260,265],"pre",{"className":261,"code":262,"language":263,"meta":264,"style":264},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Module scope runs once per instance.\nconst bootStart = performance.now();\nlet coldStart = true;\nconst initDone = (async () => { \u002F* create clients, load config *\u002F })();\nexport async function handler(req, res) {\n  await initDone;\n  const init = coldStart ? (performance.now() - bootStart).toFixed(1) : '0';\n  res.setHeader('Server-Timing', `cold;desc=\"${coldStart}\", init;dur=${init}`);\n  coldStart = false;\n  \u002F\u002F ... handle request\n}\n\u002F\u002F trade-off: performance.now() at module scope misses runtime startup before your\n\u002F\u002F code loads; combine with the platform's reported init duration.\n","javascript","",[211,266,267,275,300,318,349,380,389,438,472,485,491,497,503],{"__ignoreMap":264},[268,269,271],"span",{"class":139,"line":270},1,[268,272,274],{"class":273},"sjfSM","\u002F\u002F Module scope runs once per instance.\n",[268,276,278,282,286,289,293,297],{"class":139,"line":277},2,[268,279,281],{"class":280},"sPARh","const",[268,283,285],{"class":284},"sPXB4"," bootStart",[268,287,288],{"class":280}," =",[268,290,292],{"class":291},"saISM"," performance.",[268,294,296],{"class":295},"smZ65","now",[268,298,299],{"class":291},"();\n",[268,301,303,306,309,312,315],{"class":139,"line":302},3,[268,304,305],{"class":280},"let",[268,307,308],{"class":291}," coldStart ",[268,310,311],{"class":280},"=",[268,313,314],{"class":284}," true",[268,316,317],{"class":291},";\n",[268,319,321,323,326,328,331,334,337,340,343,346],{"class":139,"line":320},4,[268,322,281],{"class":280},[268,324,325],{"class":284}," initDone",[268,327,288],{"class":280},[268,329,330],{"class":291}," (",[268,332,333],{"class":280},"async",[268,335,336],{"class":291}," () ",[268,338,339],{"class":280},"=>",[268,341,342],{"class":291}," { ",[268,344,345],{"class":273},"\u002F* create clients, load config *\u002F",[268,347,348],{"class":291}," })();\n",[268,350,352,355,358,361,364,367,371,374,377],{"class":139,"line":351},5,[268,353,354],{"class":280},"export",[268,356,357],{"class":280}," async",[268,359,360],{"class":280}," function",[268,362,363],{"class":295}," handler",[268,365,366],{"class":291},"(",[268,368,370],{"class":369},"sQw3B","req",[268,372,373],{"class":291},", ",[268,375,376],{"class":369},"res",[268,378,379],{"class":291},") {\n",[268,381,383,386],{"class":139,"line":382},6,[268,384,385],{"class":280},"  await",[268,387,388],{"class":291}," initDone;\n",[268,390,392,395,398,400,402,405,408,410,413,416,419,422,424,426,429,432,436],{"class":139,"line":391},7,[268,393,394],{"class":280},"  const",[268,396,397],{"class":284}," init",[268,399,288],{"class":280},[268,401,308],{"class":291},[268,403,404],{"class":280},"?",[268,406,407],{"class":291}," (performance.",[268,409,296],{"class":295},[268,411,412],{"class":291},"() ",[268,414,415],{"class":280},"-",[268,417,418],{"class":291}," bootStart).",[268,420,421],{"class":295},"toFixed",[268,423,366],{"class":291},[268,425,64],{"class":284},[268,427,428],{"class":291},") ",[268,430,431],{"class":280},":",[268,433,435],{"class":434},"sZ8jY"," '0'",[268,437,317],{"class":291},[268,439,441,444,447,449,452,454,457,460,463,466,469],{"class":139,"line":440},8,[268,442,443],{"class":291},"  res.",[268,445,446],{"class":295},"setHeader",[268,448,366],{"class":291},[268,450,451],{"class":434},"'Server-Timing'",[268,453,373],{"class":291},[268,455,456],{"class":434},"`cold;desc=\"${",[268,458,459],{"class":291},"coldStart",[268,461,462],{"class":434},"}\", init;dur=${",[268,464,465],{"class":291},"init",[268,467,468],{"class":434},"}`",[268,470,471],{"class":291},");\n",[268,473,475,478,480,483],{"class":139,"line":474},9,[268,476,477],{"class":291},"  coldStart ",[268,479,311],{"class":280},[268,481,482],{"class":284}," false",[268,484,317],{"class":291},[268,486,488],{"class":139,"line":487},10,[268,489,490],{"class":273},"  \u002F\u002F ... handle request\n",[268,492,494],{"class":139,"line":493},11,[268,495,496],{"class":291},"}\n",[268,498,500],{"class":139,"line":499},12,[268,501,502],{"class":273},"\u002F\u002F trade-off: performance.now() at module scope misses runtime startup before your\n",[268,504,506],{"class":139,"line":505},13,[268,507,508],{"class":273},"\u002F\u002F code loads; combine with the platform's reported init duration.\n",[254,510,512],{"id":511},"_2-shrink-the-function-bundle","2. Shrink the function bundle",[15,514,515],{},"Bundle and tree-shake server code, mark large unused dependencies as external or remove them, and split routes into separate functions so each loads only its code. Avoid importing whole SDKs when a modular client exists.",[254,517,519],{"id":518},"_3-defer-and-reuse-initialisation","3. Defer and reuse initialisation",[15,521,522],{},"Create clients lazily on first use, reuse them across invocations (module-scope variables), and avoid work at startup that is not needed for most requests.",[254,524,526],{"id":525},"_4-use-connection-pooling-and-http-keep-alive","4. Use connection pooling and HTTP keep-alive",[15,528,529],{},"Use a database proxy or HTTP-based data API designed for serverless (connection poolers), and enable keep-alive for outgoing HTTP calls so warm instances reuse connections.",[15,531,532],{},[40,533,47,536,47,539,47,542,47,544,47,547,47,549,47,556,47,562,47,567,47,571,47,576,47,580,47,584,47,588,47,592,47,596,47,601,47],{"viewBox":534,"width":43,"role":44,"ariaLabel":535,"style":46},"0 0 760 194","Bar chart of cold start initialisation time after successive optimizations of one function.",[49,537],{"className":538,"x":53,"y":53,"width":43,"height":43,"fill":54},[52],[56,540,541],{},"Cold start init duration by change (Node.js function)",[60,543,535],{},[49,545],{"x":64,"y":64,"width":65,"height":546,"rx":67,"fill":68,"stroke":69,"style":70},"192",[72,548,541],{"x":74,"y":75,"fill":69,"style":76},[72,550,555],{"x":551,"y":552,"fill":69,"style":553,"textAnchor":554},"217.5","70.0","font-size:13px","end","Baseline (6MB bundle, eager init)",[49,557],{"x":558,"y":85,"width":559,"height":560,"rx":88,"fill":68,"stroke":69,"style":561},"229.5","438.5","19","fill-opacity:0.7;stroke-opacity:0.35",[72,563,566],{"x":564,"y":552,"fill":69,"style":565},"674.0","font-size:12px;font-weight:600","900ms",[72,568,570],{"x":551,"y":569,"fill":69,"style":553,"textAnchor":554},"101.0","Tree-shaken bundle (1.2MB)",[49,572],{"x":558,"y":573,"width":574,"height":560,"rx":88,"fill":133,"stroke":133,"style":575},"87.0","253.3","fill-opacity:0.55;stroke-opacity:0.9",[72,577,579],{"x":578,"y":569,"fill":69,"style":565},"488.9","520ms",[72,581,583],{"x":551,"y":582,"fill":69,"style":553,"textAnchor":554},"132.0","+ lazy SDK clients",[49,585],{"x":558,"y":586,"width":587,"height":560,"rx":88,"fill":133,"stroke":133,"style":575},"118.0","165.7",[72,589,591],{"x":590,"y":582,"fill":69,"style":565},"401.2","340ms",[72,593,595],{"x":551,"y":594,"fill":69,"style":553,"textAnchor":554},"163.0","+ pooled DB via proxy",[49,597],{"x":558,"y":598,"width":599,"height":560,"rx":88,"fill":89,"stroke":90,"style":600},"149.0","102.3","fill-opacity:0.7;stroke-opacity:0.9",[72,602,604],{"x":603,"y":594,"fill":69,"style":565},"337.8","210ms",[184,606,608],{"id":607},"verification","Verification",[15,610,611,612,615],{},"Track the share of requests with ",[211,613,614],{},"cold=true"," and their TTFB in RUM or logs. After changes, init duration should drop and the TTFB tail (p90, p95) should tighten. Check that warm request latency did not regress (lazy initialisation can shift work into the first request that needs it).",[184,617,619],{"id":618},"worked-example-a-marketing-site-on-serverless-ssr","Worked Example: A Marketing Site on Serverless SSR",[15,621,622,623,626],{},"A B2B company's marketing site rendered every page with serverless SSR. Traffic was modest and spread across hundreds of pages, so about 18% of requests hit cold instances. Cold TTFB was 1.6–2.4 seconds; warm TTFB 220ms; overall TTFB p75 was 780ms and p90 2.1 seconds. The team cached rendered HTML at the CDN with ",[211,624,625],{},"s-maxage=600, stale-while-revalidate=86400"," (most pages changed rarely), split the single large function into per-route functions, and replaced a full cloud SDK import with modular clients. Cache hit ratio for HTML reached 96%, so cold starts affected under 1% of navigations; cold init time itself fell from 1.3 seconds to 380ms. TTFB p75 dropped to 190ms and p90 to 420ms.",[15,628,629],{},[40,630,47,633,47,636,47,639,47,641,47,658,47,661,47,663,47,668,47,674,47,677,47,682,47,689,47,695,47,699,47,704,47,707,47,710,47,712,47,715,47,718,47,721,47,724,47,727,47,730,47,734,47,736,47,739,47,742,47,745,47,749,47,752,47,755,47],{"viewBox":631,"width":43,"role":44,"ariaLabel":632,"style":46},"0 0 760 325","Decision sequence for reducing the impact of serverless cold starts on a given route.",[49,634],{"className":635,"x":53,"y":53,"width":43,"height":43,"fill":54},[52],[56,637,638],{},"How to deal with cold starts on a route",[60,640,632],{},[642,643,644],"defs",{},[645,646,653],"marker",{"id":647,"viewBox":648,"refX":649,"refY":650,"markerWidth":651,"markerHeight":651,"orient":652},"fa8b14c36b","0 0 10 10","9","5","7","auto-start-reverse",[654,655],"path",{"d":656,"fill":69,"style":657},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[49,659],{"x":64,"y":64,"width":65,"height":660,"rx":67,"fill":68,"stroke":69,"style":70},"323",[72,662,638],{"x":74,"y":75,"fill":69,"style":76},[49,664],{"x":74,"y":85,"width":665,"height":666,"rx":667,"fill":69,"stroke":69,"style":107},"320.0","35.0","6",[72,669,673],{"x":670,"y":671,"fill":69,"style":672,"textAnchor":97},"188.0","78.0","font-size:13px;font-weight:700","Is the response the same for many users?",[49,675],{"x":676,"y":85,"width":665,"height":666,"rx":667,"fill":89,"stroke":90,"style":91},"412.0",[72,678,681],{"x":679,"y":671,"fill":69,"style":680,"textAnchor":97},"572.0","font-size:12.5px","Cache HTML at the CDN or pre-render",[139,683],{"x1":684,"y1":95,"x2":685,"y2":95,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"348.0","410.0","1.5","stroke-opacity:0.6","url(#fa8b14c36b)",[72,690,694],{"x":691,"y":692,"fill":133,"style":693,"textAnchor":97},"380.0","66.5","font-size:11.5px;font-weight:700","yes",[139,696],{"x1":670,"y1":697,"x2":670,"y2":698,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"91.0","125.0",[72,700,703],{"x":701,"y":702,"fill":149,"style":693},"196.0","113.0","no",[49,705],{"x":74,"y":706,"width":665,"height":666,"rx":667,"fill":69,"stroke":69,"style":107},"127.0",[72,708,709],{"x":670,"y":598,"fill":69,"style":672,"textAnchor":97},"Is init time over ~300ms?",[49,711],{"x":676,"y":706,"width":665,"height":666,"rx":667,"fill":133,"stroke":133,"style":134},[72,713,714],{"x":679,"y":598,"fill":69,"style":680,"textAnchor":97},"Shrink bundle and defer initialisation",[139,716],{"x1":684,"y1":717,"x2":685,"y2":717,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"144.5",[72,719,694],{"x":691,"y":720,"fill":133,"style":693,"textAnchor":97},"137.5",[139,722],{"x1":670,"y1":723,"x2":670,"y2":701,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"162.0",[72,725,703],{"x":701,"y":726,"fill":149,"style":693},"184.0",[49,728],{"x":74,"y":729,"width":665,"height":666,"rx":667,"fill":69,"stroke":69,"style":107},"198.0",[72,731,733],{"x":670,"y":732,"fill":69,"style":672,"textAnchor":97},"220.0","Is traffic steady and latency critical?",[49,735],{"x":676,"y":729,"width":665,"height":666,"rx":667,"fill":133,"stroke":133,"style":134},[72,737,738],{"x":679,"y":732,"fill":69,"style":680,"textAnchor":97},"Provisioned or minimum instances",[139,740],{"x1":684,"y1":741,"x2":685,"y2":741,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"215.5",[72,743,694],{"x":691,"y":744,"fill":133,"style":693,"textAnchor":97},"208.5",[139,746],{"x1":670,"y1":747,"x2":670,"y2":748,"stroke":69,"strokeWidth":686,"style":687,"markerEnd":688},"233.0","267.0",[72,750,703],{"x":701,"y":751,"fill":149,"style":693},"255.0",[49,753],{"x":74,"y":754,"width":665,"height":75,"rx":667,"fill":89,"stroke":90,"style":91},"269.0",[72,756,758],{"x":670,"y":757,"fill":69,"style":680,"textAnchor":97},"290.5","Pool connections and accept rare cold starts",[184,760,762],{"id":761},"avoiding-cold-starts-altogether","Avoiding Cold Starts Altogether",[15,764,765],{},"The most effective fix is often to avoid running a function for most requests. For content that is the same for many users, cache HTML at the CDN or pre-render at build time (static generation or incremental static regeneration), so functions only run for cache misses and revalidations. For dynamic pages, platform features can help: provisioned or minimum instances keep a number of instances warm (at a cost), and some platforms offer faster-starting runtimes or snapshotting that reduces init time. Edge functions on V8 isolates start in milliseconds, but have limited APIs and should stay close to their data.",[184,767,769],{"id":768},"common-mistakes","Common Mistakes",[189,771,772,778,784,790],{},[192,773,774,777],{},[30,775,776],{},"Scheduled \"warming\" pings."," Keep one instance warm but do nothing for concurrent requests or traffic spikes.",[192,779,780,783],{},[30,781,782],{},"Importing everything at module scope."," Pays the full cost on every cold start.",[192,785,786,789],{},[30,787,788],{},"New database connections per request."," Slow and may exhaust database limits.",[192,791,792,795],{},[30,793,794],{},"Ignoring the tail."," Medians hide cold starts; look at p90 and p95.",[184,797,799],{"id":798},"edge-cases","Edge Cases",[15,801,802,805],{},[30,803,804],{},"Deployments."," Every deploy starts new instances; staggered rollouts and pre-warming reduce the spike.",[15,807,808,811],{},[30,809,810],{},"Multi-region."," Low-traffic regions see more cold starts; consider fewer regions with CDN caching in front.",[15,813,814,817],{},[30,815,816],{},"Memory settings."," On some platforms, higher memory allocation also gives more CPU, speeding up initialisation.",[15,819,820,823],{},[30,821,822],{},"Language runtimes."," Runtimes differ in startup cost; JVM-based functions benefit most from snapshotting features.",[184,825,827],{"id":826},"faq","FAQ",[829,830,833,837],"details",{"className":831},[832],"faq-item",[834,835,836],"summary",{},"How long is a typical cold start?",[15,838,839],{},"From about 100ms for small functions on fast runtimes to several seconds for large bundles with heavy initialisation. Measure your own functions.",[829,841,843,846],{"className":842},[832],[834,844,845],{},"Do warming pings help?",[15,847,848],{},"Only slightly. They keep one instance warm, but concurrent requests and spikes still create new instances.",[829,850,852,855],{"className":851},[832],[834,853,854],{},"Is provisioned concurrency worth it?",[15,856,857],{},"For latency-sensitive, steady-traffic routes, often yes. It costs money for idle capacity, so combine it with caching to keep the number of needed instances small.",[829,859,861,864],{"className":860},[832],[834,862,863],{},"Do edge functions have cold starts?",[15,865,866],{},"Isolate-based edge functions start very quickly (milliseconds), but calling distant databases from the edge can add more latency than the cold start saves.",[829,868,870,873],{"className":869},[832],[834,871,872],{},"How do I know if a request was cold?",[15,874,875],{},"Track a module-level flag as in the example, or read the platform's init duration from logs, and report it via Server-Timing.",[829,877,879,882],{"className":878},[832],[834,880,881],{},"Does bundle size really matter on the server?",[15,883,884],{},"Yes. Loading and evaluating large bundles is a major part of cold start time. Server code deserves the same tree-shaking attention as client code.",[829,886,888,891],{"className":887},[832],[834,889,890],{},"Should every page be server-rendered on request?",[15,892,893],{},"No. Pages that are the same for all users should be static or cached at the CDN. Reserve per-request rendering for genuinely dynamic responses.",[829,895,897,900],{"className":896},[832],[834,898,899],{},"Do cold starts affect Core Web Vitals?",[15,901,902],{},"Yes, through TTFB, which delays FCP and LCP. Because they hit a minority of requests, they mostly affect the upper percentiles, but on low-traffic sites they can move p75.",[829,904,906,909],{"className":905},[832],[834,907,908],{},"Can I pre-warm functions after a deploy?",[15,910,911],{},"Some platforms support it; otherwise, a script that requests key routes in each region after deployment reduces the cold-start spike for early visitors.",[829,913,915,918],{"className":914},[832],[834,916,917],{},"Does the runtime language matter?",[15,919,920],{},"Yes. Lightweight runtimes start faster; heavier ones benefit more from snapshot features. Within one language, bundle size and initialisation work usually matter most.",[184,922,924],{"id":923},"related","Related",[189,926,927,934,941],{},[192,928,929,933],{},[19,930,932],{"href":931},"\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Fdiagnosing-slow-ttfb-with-server-timing\u002F","Diagnosing slow TTFB with Server-Timing"," — measure init and handler time.",[192,935,936,940],{},[19,937,939],{"href":938},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained\u002Fcache-control-for-html-documents\u002F","Cache-Control for HTML documents"," — cache HTML to avoid running functions.",[192,942,943,947],{},[19,944,946],{"href":945},"\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Fnuxt-route-rules-for-hybrid-rendering\u002F","Nuxt route rules for hybrid rendering"," — choose static, cached or dynamic per route.",[949,950,952],"script",{"type":951},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to Fix TTFB from Serverless Cold Starts\",\n  \"description\": \"Why serverless cold starts slow down TTFB, how to measure their share, and the code and platform changes that reduce or avoid them.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Measure cold start share and cost\",\n      \"text\": \"Measure cold start share and cost\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Shrink the function bundle\",\n      \"text\": \"Bundle and tree-shake server code, mark large unused dependencies as external or remove them, and split routes into separate functions so each loads only its code.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Defer and reuse initialisation\",\n      \"text\": \"Create clients lazily on first use, reuse them across invocations (module-scope variables), and avoid work at startup that is not needed for most requests.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Use connection pooling and HTTP keep-alive\",\n      \"text\": \"Use a database proxy or HTTP-based data API designed for serverless (connection poolers), and enable keep-alive for outgoing HTTP calls so warm instances reuse connections.\"\n    }\n  ]\n}\n",[949,954,955],{"type":951},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"How to Fix TTFB from Serverless Cold Starts\",\n  \"description\": \"Why serverless cold starts slow down TTFB, how to measure their share, and the code and platform changes that reduce or avoid them.\",\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\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts\u002F\"\n  }\n}\n",[949,957,958],{"type":951},"\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\": \"Time to First Byte (TTFB) Optimization\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Fixing TTFB from Serverless Cold Starts\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts\u002F\"\n    }\n  ]\n}\n",[960,961,962],"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 .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}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);}",{"title":264,"searchDepth":277,"depth":277,"links":964},[965,966,967,973,974,975,976,977,978,979],{"id":186,"depth":277,"text":187},{"id":223,"depth":277,"text":224},{"id":251,"depth":277,"text":252,"children":968},[969,970,971,972],{"id":256,"depth":302,"text":257},{"id":511,"depth":302,"text":512},{"id":518,"depth":302,"text":519},{"id":525,"depth":302,"text":526},{"id":607,"depth":277,"text":608},{"id":618,"depth":277,"text":619},{"id":761,"depth":277,"text":762},{"id":768,"depth":277,"text":769},{"id":798,"depth":277,"text":799},{"id":826,"depth":277,"text":827},{"id":923,"depth":277,"text":924},"Why serverless cold starts slow down TTFB, how to measure their share, and the code and platform changes that reduce or avoid them.","md",{"slug":983,"type":984,"breadcrumb":985,"datePublished":994,"dateModified":994},"fixing-ttfb-from-serverless-cold-starts","article",[986,989,990,992],{"name":987,"url":988},"Home","\u002F",{"name":27,"url":26},{"name":991,"url":21},"Time to First Byte (TTFB) Optimization",{"name":5,"url":993},"\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts\u002F","2026-10-06",true,"\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts",{"title":998,"description":999},"Fixing Slow TTFB from Serverless Cold Starts","Cold starts add hundreds of milliseconds to TTFB on Lambda, Vercel and Netlify functions. Shrink bundles, defer init, pool connections and cache HTML to avoid them.","network-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Ffixing-ttfb-from-serverless-cold-starts\u002Findex","JbizKxoZftu1K6eMjIcsLes5Hg1WdKMYznmifCmGc3Q",[1003,1007],{"title":1004,"path":1005,"stem":1006,"children":-1},"Eliminating Redirect Chains","\u002Fnetwork-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Feliminating-redirect-chains","network-protocol-optimization\u002Ftime-to-first-byte-optimization\u002Feliminating-redirect-chains\u002Findex",{"title":1008,"path":1009,"stem":1010,"children":-1},"Rendering & CSS Performance","\u002Frendering-css-performance","rendering-css-performance\u002Findex",1791308072511]