[{"data":1,"prerenderedAt":847},["ShallowReactive",2],{"content:\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F":3,"surroundings:\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F":839},{"id":4,"title":5,"body":6,"description":819,"extension":820,"meta":821,"navigation":832,"path":833,"seo":834,"stem":837,"__hash__":838},"content\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002Findex.md","Configuring stale-if-error for origin outages",{"type":7,"value":8,"toc":807},"minimark",[9,13,28,45,177,182,185,271,275,292,301,320,340,352,356,359,364,367,439,446,450,453,518,527,530,534,537,604,610,614,629,632,636,643,744,756,760,792,797,800,803],[10,11,5],"h1",{"id":12},"configuring-stale-if-error-for-origin-outages",[14,15,16,17,22,23,27],"p",{},"This scenario sits under the ",[18,19,21],"a",{"href":20},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002F","CDN edge caching configuration"," guide inside ",[18,24,26],{"href":25},"\u002Fadvanced-caching-strategies-cdn-architecture\u002F","Advanced Caching Strategies & CDN Architecture",", and addresses one failure mode: your origin returns 5xx or times out, and the edge dutifully forwards the error to users instead of falling back to the perfectly good copy it cached minutes ago.",[14,29,30,31,35,36,39,40,44],{},"The fix is the RFC 5861 ",[32,33,34],"code",{},"stale-if-error"," directive, usually paired with ",[32,37,38],{},"stale-while-revalidate",". Configured correctly, an origin outage becomes invisible: the edge keeps serving stale HTML and JSON with a fast TTFB (≤ 200ms) while the origin recovers, and your ",[18,41,43],{"href":42},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F","Largest Contentful Paint"," stays under 2.5s instead of collapsing into an error page. The danger is the opposite failure — serving stale content forever, or serving it when you should not — so the configuration has to be precise.",[14,46,47],{},[48,49,56,57,56,61,56,65,56,75,56,82,56,91,56,97,56,102,56,109,56,113,56,118,56,122,56,128,56,132,56,135,56,138,56,144,56,148,56,154,56,157,56,162,56,167,56,172,56],"svg",{"xmlns":50,"viewBox":51,"width":52,"role":53,"ariaLabel":54,"style":55},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0 0 760 300","100%","img","Decision flow for how the edge responds when the origin returns an error, using stale-if-error","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:#001d3d"," ",[58,59,60],"title",{},"stale-if-error decision flow",[62,63,64],"desc",{},"How the edge chooses between serving a stale cached copy and forwarding the origin error.",[66,67],"rect",{"x":68,"y":68,"width":69,"height":70,"rx":71,"fill":72,"stroke":73,"style":74},"1","758","298","10","none","currentColor","stroke-opacity:0.18",[76,77,81],"text",{"x":78,"y":79,"fill":73,"style":80},"24","36","font-size:17px;font-weight:700","Edge behaviour during an origin error",[66,83],{"x":84,"y":85,"width":86,"height":87,"rx":88,"fill":89,"stroke":89,"style":90},"44","64","150","56","6","#0466c8","fill-opacity:0.14",[76,92,96],{"x":93,"y":94,"fill":73,"style":95},"119","88","font-size:12px;font-weight:600;text-anchor:middle","Origin returns",[76,98,101],{"x":93,"y":99,"fill":73,"style":100},"106","font-size:12px;text-anchor:middle","5xx \u002F timeout",[103,104],"line",{"x1":105,"y1":106,"x2":107,"y2":106,"stroke":73,"style":108},"194","92","244","stroke-opacity:0.5",[66,110],{"x":107,"y":85,"width":111,"height":87,"rx":88,"fill":73,"stroke":73,"style":112},"170","stroke-opacity:0.4;fill-opacity:0.06",[76,114,117],{"x":115,"y":116,"fill":73,"style":95},"329","86","Stale copy exists",[76,119,121],{"x":115,"y":120,"fill":73,"style":100},"104","within s-i-e window?",[66,123],{"x":124,"y":85,"width":107,"height":87,"rx":88,"fill":125,"stroke":126,"style":127},"470","#ffc300","#b8860b","fill-opacity:0.22",[76,129,131],{"x":130,"y":116,"fill":73,"style":95},"592","YES: serve STALE 200",[76,133,134],{"x":130,"y":120,"fill":73,"style":100},"TTFB held under 200ms",[103,136],{"x1":137,"y1":106,"x2":124,"y2":106,"stroke":73,"style":108},"414",[76,139,143],{"x":140,"y":141,"fill":73,"style":142},"442","84","font-size:11px;text-anchor:middle","yes",[103,145],{"x1":115,"y1":146,"x2":115,"y2":147,"stroke":73,"style":108},"120","160",[76,149,153],{"x":150,"y":151,"fill":73,"style":152},"345","142","font-size:11px","no",[66,155],{"x":107,"y":147,"width":107,"height":156,"rx":88,"fill":73,"stroke":73,"style":112},"50",[76,158,161],{"x":159,"y":160,"fill":73,"style":95},"366","190","Forward error: 5xx",[103,163],{"x1":78,"y1":164,"x2":165,"y2":164,"stroke":73,"style":166},"238","736","stroke-opacity:0.3",[76,168,171],{"x":78,"y":169,"fill":73,"style":170},"262","font-size:12px","Size the window to p95 recovery time; pair with origin-side alarms.",[76,173,176],{"x":78,"y":174,"fill":73,"style":175},"284","font-size:12px;fill-opacity:0.8","Cap the window to seconds for prices, stock, and auth-sensitive routes.",[178,179,181],"h2",{"id":180},"rapid-diagnosis","Rapid diagnosis",[14,183,184],{},"Before changing headers, confirm the edge is actually forwarding origin errors rather than absorbing them.",[186,187,188,210,243,258,265],"ul",{},[189,190,191,192,195,196,199,200,199,203,206,207,209],"li",{},"Take the origin down or point a request at a known-failing route, then ",[32,193,194],{},"curl -I"," the edge URL. A ",[32,197,198],{},"502","\u002F",[32,201,202],{},"503",[32,204,205],{},"504"," reaching the client means no ",[32,208,34],{}," fallback is active.",[189,211,212,213,216,217,216,220,223,224,227,228,216,231,234,235,238,239,242],{},"Inspect the cache-status header (",[32,214,215],{},"CF-Cache-Status",", ",[32,218,219],{},"X-Cache",[32,221,222],{},"Fastly"," debug headers, ",[32,225,226],{},"x-vercel-cache","). During the outage you want to see a hit\u002Fstale indicator (",[32,229,230],{},"STALE",[32,232,233],{},"HIT","), not ",[32,236,237],{},"MISS"," or ",[32,240,241],{},"ERROR",".",[189,244,245,246,249,250,254,255,257],{},"Check the ",[32,247,248],{},"Cache-Control"," on the ",[251,252,253],"em",{},"origin"," response in the browser Network tab. If ",[32,256,34],{}," is absent, the edge has nothing authorising a fallback.",[189,259,260,261,264],{},"Confirm the resource was cached at all before the outage — a route with ",[32,262,263],{},"Cache-Control: no-store"," or a cookie-fragmented cache key has no stale copy to fall back to.",[189,266,267,268,270],{},"Look at the edge TTL: if the object already expired past the ",[32,269,34],{}," window, the edge correctly stops serving it.",[178,272,274],{"id":273},"root-cause-analysis","Root cause analysis",[14,276,277,281,282,285,286,288,289,291],{},[278,279,280],"strong",{},"1. The directive is simply missing."," The most common cause: origin responses carry ",[32,283,284],{},"max-age"," but no ",[32,287,34],{},". The edge has a fresh-or-revalidate model only, so on a ",[32,290,205],{}," it has no instruction to reuse the expired object and passes the error through.",[14,293,294,56,297,300],{},[278,295,296],{},"2. The grace window is too short.",[32,298,299],{},"stale-if-error=60"," only covers a one-minute blip. A real deploy failure or database incident runs for minutes to hours; once the window lapses, the edge resumes forwarding errors. The window must be sized to your realistic mean-time-to-recovery, not to a hypothetical.",[14,302,303,56,306,216,309,312,313,199,316,319],{},[278,304,305],{},"3. The route was never cacheable.",[32,307,308],{},"Set-Cookie",[32,310,311],{},"Vary: Cookie",", or ",[32,314,315],{},"Cache-Control: private",[32,317,318],{},"no-store"," on the HTML means the edge never stored a shared copy, so there is nothing to serve stale. Personalised pages are the classic blind spot here.",[14,321,322,325,326,328,329,332,333,335,336,339],{},[278,323,324],{},"4. The CDN does not honour the standard directive."," Several CDNs ignore the HTTP ",[32,327,34],{}," directive and require their own configuration knob (Cloudflare's ",[251,330,331],{},"Always Online"," \u002F Tiered Cache serve-stale, Fastly's VCL ",[32,334,34],{}," in ",[32,337,338],{},"vcl_fetch",", Akamai's downstream caching settings). Setting the header alone does nothing on those platforms.",[14,341,342,345,346,348,349,351],{},[278,343,344],{},"5. The error window is masking a real incident."," A subtler failure mode is success that hides a problem. Once ",[32,347,34],{}," is serving day-old content, edge status codes look healthy even though the origin has been down for an hour. Teams that alarm on edge 5xx rate will see nothing fire while customers quietly view stale data. The directive is doing its job, but observability has to move to the origin tier — otherwise the safety net becomes a blindfold. This is not a reason to avoid ",[32,350,34],{},"; it is a reason to pair it with origin-side error-rate and saturation alarms so the outage is still visible to you even when it is invisible to users.",[178,353,355],{"id":354},"step-by-step-resolution","Step-by-step resolution",[14,357,358],{},"Apply these in order of impact; each lists the expected outcome.",[360,361,363],"h3",{"id":362},"_1-add-stale-if-error-to-origin-responses","1. Add stale-if-error to origin responses",[14,365,366],{},"Emit both grace directives on cacheable HTML and API payloads from the origin:",[368,369,374],"pre",{"className":370,"code":371,"language":372,"meta":373,"style":373},"language-nginx shiki shiki-themes github-light-high-contrast github-light-high-contrast github-light-high-contrast","# Origin (or shielding tier) response for cacheable HTML.\nlocation \u002F {\n  add_header Cache-Control \"public, max-age=60, stale-while-revalidate=600, stale-if-error=86400\";\n  # trade-off: an 86400s (24h) error window can serve day-old content during a\n  # long outage. Do NOT use this length for prices, stock, or auth-sensitive\n  # pages — cap stale-if-error to seconds there and prefer an explicit error.\n}\n","nginx","",[32,375,376,384,399,415,421,427,433],{"__ignoreMap":373},[377,378,380],"span",{"class":103,"line":379},1,[377,381,383],{"class":382},"sIIH1","# Origin (or shielding tier) response for cacheable HTML.\n",[377,385,387,391,395],{"class":103,"line":386},2,[377,388,390],{"class":389},"sP5qI","location",[377,392,394],{"class":393},"seIZK"," \u002F ",[377,396,398],{"class":397},"syybb","{\n",[377,400,402,405,408,412],{"class":103,"line":401},3,[377,403,404],{"class":389},"  add_header ",[377,406,407],{"class":397},"Cache-Control ",[377,409,411],{"class":410},"s-_DF","\"public, max-age=60, stale-while-revalidate=600, stale-if-error=86400\"",[377,413,414],{"class":397},";\n",[377,416,418],{"class":103,"line":417},4,[377,419,420],{"class":382},"  # trade-off: an 86400s (24h) error window can serve day-old content during a\n",[377,422,424],{"class":103,"line":423},5,[377,425,426],{"class":382},"  # long outage. Do NOT use this length for prices, stock, or auth-sensitive\n",[377,428,430],{"class":103,"line":429},6,[377,431,432],{"class":382},"  # pages — cap stale-if-error to seconds there and prefer an explicit error.\n",[377,434,436],{"class":103,"line":435},7,[377,437,438],{"class":397},"}\n",[14,440,441,442,445],{},"Expected outcome: during a ",[32,443,444],{},"5xx","\u002Ftimeout, the edge serves the last good copy for up to 24h instead of an error page, holding TTFB at edge-cache speed (≤ 50ms) rather than an origin round-trip plus failure.",[360,447,449],{"id":448},"_2-enable-serve-stale-on-cdns-that-ignore-the-header","2. Enable serve-stale on CDNs that ignore the header",[14,451,452],{},"On Fastly, make the behaviour explicit in VCL so a fetch failure reuses stale:",[368,454,458],{"className":455,"code":456,"language":457,"meta":373,"style":373},"language-vcl shiki shiki-themes github-light-high-contrast github-light-high-contrast github-light-high-contrast","sub vcl_fetch {\n  # Reuse cached object for 24h if origin errors, refresh quietly for 10m.\n  set beresp.stale_if_error = 86400s;\n  set beresp.stale_while_revalidate = 600s;\n  if (beresp.status >= 500 && stale.exists) {\n    return (deliver_stale);\n  }\n  # trade-off: deliver_stale masks origin 5xx from monitoring. Keep origin\n  # error rate alarms on the origin tier, not on edge status codes, or a\n  # multi-hour outage will look healthy from the edge.\n}\n","vcl",[32,459,460,465,470,475,480,485,490,495,501,507,513],{"__ignoreMap":373},[377,461,462],{"class":103,"line":379},[377,463,464],{},"sub vcl_fetch {\n",[377,466,467],{"class":103,"line":386},[377,468,469],{},"  # Reuse cached object for 24h if origin errors, refresh quietly for 10m.\n",[377,471,472],{"class":103,"line":401},[377,473,474],{},"  set beresp.stale_if_error = 86400s;\n",[377,476,477],{"class":103,"line":417},[377,478,479],{},"  set beresp.stale_while_revalidate = 600s;\n",[377,481,482],{"class":103,"line":423},[377,483,484],{},"  if (beresp.status >= 500 && stale.exists) {\n",[377,486,487],{"class":103,"line":429},[377,488,489],{},"    return (deliver_stale);\n",[377,491,492],{"class":103,"line":435},[377,493,494],{},"  }\n",[377,496,498],{"class":103,"line":497},8,[377,499,500],{},"  # trade-off: deliver_stale masks origin 5xx from monitoring. Keep origin\n",[377,502,504],{"class":103,"line":503},9,[377,505,506],{},"  # error rate alarms on the origin tier, not on edge status codes, or a\n",[377,508,510],{"class":103,"line":509},10,[377,511,512],{},"  # multi-hour outage will look healthy from the edge.\n",[377,514,516],{"class":103,"line":515},11,[377,517,438],{},[14,519,520,521,523,524,526],{},"On Cloudflare, enable ",[251,522,331],{}," and Tiered Cache, or set ",[32,525,248],{}," via a Cache Rule, since the worker\u002Fedge honours serve-stale through those settings rather than the raw directive alone.",[14,528,529],{},"Expected outcome: platforms that drop the standard directive now fall back to stale, eliminating the silent gap where the header was present but inert.",[360,531,533],{"id":532},"_3-make-the-route-cacheable-in-the-first-place","3. Make the route cacheable in the first place",[14,535,536],{},"Strip personalisation from the cache key so a shared stale copy exists:",[368,538,540],{"className":370,"code":539,"language":372,"meta":373,"style":373},"# Don't fragment the HTML cache on analytics\u002Fsession cookies.\nproxy_cache_key \"$scheme$host$request_uri\";\nproxy_ignore_headers Set-Cookie;\nproxy_hide_header Set-Cookie;\n# trade-off: this is only safe for genuinely shared, anonymous HTML.\n# Applying it to logged-in pages leaks one user's cached page to another —\n# segment personalised routes into a separate, non-shared cache.\n",[32,541,542,547,574,582,589,594,599],{"__ignoreMap":373},[377,543,544],{"class":103,"line":379},[377,545,546],{"class":382},"# Don't fragment the HTML cache on analytics\u002Fsession cookies.\n",[377,548,549,552,555,558,561,564,566,569,572],{"class":103,"line":386},[377,550,551],{"class":389},"proxy_cache_key ",[377,553,554],{"class":410},"\"$",[377,556,557],{"class":397},"scheme",[377,559,560],{"class":410},"$",[377,562,563],{"class":397},"host",[377,565,560],{"class":410},[377,567,568],{"class":397},"request_uri",[377,570,571],{"class":410},"\"",[377,573,414],{"class":397},[377,575,576,579],{"class":103,"line":401},[377,577,578],{"class":389},"proxy_ignore_headers ",[377,580,581],{"class":397},"Set-Cookie;\n",[377,583,584,587],{"class":103,"line":417},[377,585,586],{"class":389},"proxy_hide_header ",[377,588,581],{"class":397},[377,590,591],{"class":103,"line":423},[377,592,593],{"class":382},"# trade-off: this is only safe for genuinely shared, anonymous HTML.\n",[377,595,596],{"class":103,"line":429},[377,597,598],{"class":382},"# Applying it to logged-in pages leaks one user's cached page to another —\n",[377,600,601],{"class":103,"line":435},[377,602,603],{"class":382},"# segment personalised routes into a separate, non-shared cache.\n",[14,605,606,607,609],{},"Expected outcome: anonymous HTML now has a shared edge object, giving ",[32,608,34],{}," something to serve and lifting baseline hit ratio above the 85% target for static routes.",[360,611,613],{"id":612},"_4-size-the-window-to-real-recovery-time","4. Size the window to real recovery time",[14,615,616,617,619,620,622,623,625,626,628],{},"Set ",[32,618,34],{}," to comfortably exceed your p95 incident duration (commonly 1-24h for HTML, shorter for data) while keeping ",[32,621,38],{}," short (300-600s) so healthy traffic refreshes promptly. The two are independent: ",[32,624,38],{}," handles the normal expiry path, ",[32,627,34],{}," handles the failure path.",[14,630,631],{},"Expected outcome: routine expiries stay fresh within ~10 minutes, while a multi-hour outage is still fully absorbed.",[178,633,635],{"id":634},"verification","Verification",[14,637,638,639,642],{},"Confirm the fallback works ",[251,640,641],{},"and"," that it heals after recovery:",[644,645,646,696,711,723,738],"ol",{},[189,647,648,651,652,654,655],{},[278,649,650],{},"Before\u002Fafter header diff."," Compare the origin ",[32,653,248],{},":\n",[368,656,660],{"className":657,"code":658,"language":659,"meta":373,"style":373},"language-bash shiki shiki-themes github-light-high-contrast github-light-high-contrast github-light-high-contrast","curl -sI https:\u002F\u002Fyourdomain.com\u002F | grep -i cache-control\n# before: cache-control: public, max-age=60\n# after:  cache-control: public, max-age=60, stale-while-revalidate=600, stale-if-error=86400\n","bash",[32,661,662,686,691],{"__ignoreMap":373},[377,663,664,667,671,674,677,680,683],{"class":103,"line":379},[377,665,666],{"class":393},"curl",[377,668,670],{"class":669},"sf6mN"," -sI",[377,672,673],{"class":410}," https:\u002F\u002Fyourdomain.com\u002F",[377,675,676],{"class":389}," |",[377,678,679],{"class":393}," grep",[377,681,682],{"class":669}," -i",[377,684,685],{"class":410}," cache-control\n",[377,687,688],{"class":103,"line":386},[377,689,690],{"class":382},"# before: cache-control: public, max-age=60\n",[377,692,693],{"class":103,"line":401},[377,694,695],{"class":382},"# after:  cache-control: public, max-age=60, stale-while-revalidate=600, stale-if-error=86400\n",[189,697,698,701,702,705,706,708,709,242],{},[278,699,700],{},"Simulate the outage."," Block the origin (firewall rule or kill the upstream) and re-request the edge. Expected: ",[32,703,704],{},"200 OK"," from cache with a ",[32,707,230],{}," cache-status, not a ",[32,710,444],{},[189,712,713,716,717,719,720,722],{},[278,714,715],{},"Confirm recovery."," Restore the origin. Within the ",[32,718,38],{}," window the edge should serve stale once more, then transparently refresh to a ",[32,721,233],{}," with the new body — verify the response content updates.",[189,724,725,728,729,731,732,734,735,737],{},[278,726,727],{},"CI assertion."," Add a synthetic check that fails the pipeline if the production ",[32,730,248],{}," for ",[32,733,199],{}," lacks ",[32,736,34],{},", so a future origin refactor cannot silently drop it.",[189,739,740,743],{},[278,741,742],{},"RUM field check."," During the next real origin blip, watch error-page rate and TTFB p75 in RUM. Expected: client-visible 5xx rate near zero and TTFB held under 200ms, even while origin error rate spikes.",[14,745,746,747,750,751,755],{},"This pattern composes with the broader edge configuration and with deliberate purging — when you ",[251,748,749],{},"do"," need to evict the stale copy after a fix, see the ",[18,752,754],{"href":753},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcache-invalidation-patterns\u002F","cache invalidation patterns"," guide.",[178,757,759],{"id":758},"related","Related",[186,761,762,767,774,781,787],{},[189,763,764,766],{},[18,765,21],{"href":20}," — the parent guide covering TTL tiers and edge rule orchestration.",[189,768,769,773],{},[18,770,772],{"href":771},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fstale-while-revalidate-implementation\u002F","Stale-while-revalidate implementation"," — the companion directive for the normal expiry path.",[189,775,776,780],{},[18,777,779],{"href":778},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained\u002F","HTTP Cache-Control headers explained"," — directive precedence and syntax behind these headers.",[189,782,783,786],{},[18,784,785],{"href":753},"Cache invalidation patterns"," — how to purge the stale object once the origin is healthy.",[189,788,789,791],{},[18,790,26],{"href":25}," — the overall caching architecture this resilience pattern belongs to.",[793,794,796],"script",{"type":795},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"Article\",\n  \"headline\": \"Configuring stale-if-error for origin outages\",\n  \"description\": \"Serve stale content during origin outages using stale-if-error and stale-while-revalidate Cache-Control directives at the CDN edge, with diagnosis, fixes, and verification.\",\n  \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F\",\n  \"datePublished\": \"2026-06-18\",\n  \"dateModified\": \"2026-06-18\",\n  \"author\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"publisher\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\", \"logo\": { \"@type\": \"ImageObject\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Flogo.svg\" } },\n  \"mainEntityOfPage\": { \"@type\": \"WebPage\", \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F\" }\n}\n",[793,798,799],{"type":795},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Serve stale content during origin outages with stale-if-error\",\n  \"step\": [\n    { \"@type\": \"HowToStep\", \"name\": \"Add stale-if-error\", \"text\": \"Emit stale-while-revalidate and stale-if-error on cacheable origin responses.\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Enable serve-stale\", \"text\": \"Configure serve-stale on CDNs that ignore the raw directive, e.g. Fastly VCL or Cloudflare Always Online.\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Make route cacheable\", \"text\": \"Strip personalisation from the cache key so a shared stale copy exists.\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Size the window\", \"text\": \"Set stale-if-error to exceed p95 incident duration while keeping stale-while-revalidate short.\" },\n    { \"@type\": \"HowToStep\", \"name\": \"Verify and monitor\", \"text\": \"Simulate an outage, confirm a STALE 200, confirm recovery, and add a CI header assertion.\" }\n  ]\n}\n",[793,801,802],{"type":795},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    { \"@type\": \"ListItem\", \"position\": 1, \"name\": \"Home\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 2, \"name\": \"Advanced Caching Strategies & CDN Architecture\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 3, \"name\": \"CDN Edge Caching Configuration\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 4, \"name\": \"Configuring stale-if-error for origin outages\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F\" }\n  ]\n}\n",[804,805,806],"style",{},"html pre.shiki code .sIIH1, html code.shiki .sIIH1{--shiki-default:#66707B;--shiki-dark:#66707B;--shiki-light:#66707B}html pre.shiki code .sP5qI, html code.shiki .sP5qI{--shiki-default:#A0111F;--shiki-dark:#A0111F;--shiki-light:#A0111F}html pre.shiki code .seIZK, html code.shiki .seIZK{--shiki-default:#702C00;--shiki-dark:#702C00;--shiki-light:#702C00}html pre.shiki code .syybb, html code.shiki .syybb{--shiki-default:#0E1116;--shiki-dark:#0E1116;--shiki-light:#0E1116}html pre.shiki code .s-_DF, html code.shiki .s-_DF{--shiki-default:#032563;--shiki-dark:#032563;--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 .sf6mN, html code.shiki .sf6mN{--shiki-default:#023B95;--shiki-dark:#023B95;--shiki-light:#023B95}",{"title":373,"searchDepth":386,"depth":386,"links":808},[809,810,811,817,818],{"id":180,"depth":386,"text":181},{"id":273,"depth":386,"text":274},{"id":354,"depth":386,"text":355,"children":812},[813,814,815,816],{"id":362,"depth":401,"text":363},{"id":448,"depth":401,"text":449},{"id":532,"depth":401,"text":533},{"id":612,"depth":401,"text":613},{"id":634,"depth":386,"text":635},{"id":758,"depth":386,"text":759},"Keep serving cached pages from the edge when the origin returns 5xx or times out, using stale-if-error and stale-while-revalidate.","md",{"slug":12,"type":822,"breadcrumb":823,"datePublished":831,"dateModified":831},"long_tail",[824,826,827,829],{"name":825,"url":199},"Home",{"name":26,"url":25},{"name":828,"url":20},"CDN Edge Caching Configuration",{"name":5,"url":830},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002F","2026-06-18",true,"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages",{"title":835,"description":836},"Configuring stale-if-error for Origin Outages","Serve stale content during origin outages using stale-if-error and stale-while-revalidate Cache-Control directives at the CDN edge. Diagnosis, fixes, and verification.","advanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Fconfiguring-stale-if-error-for-origin-outages\u002Findex","Cl4kG_OEJ0NvuE6wz7fXD0ygrwzKiDyQt1ShnvQfLng",[840,843],{"title":828,"path":841,"stem":842,"children":-1},"\u002Fadvanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration","advanced-caching-strategies-cdn-architecture\u002Fcdn-edge-caching-configuration\u002Findex",{"title":844,"path":845,"stem":846,"children":-1},"HTTP Cache-Control Headers Explained","\u002Fadvanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained","advanced-caching-strategies-cdn-architecture\u002Fhttp-cache-control-headers-explained\u002Findex",1782237170939]