CDN Black Friday Preparation Checklist: Ensuring Your Store Survives Peak Shopping

I've watched a $3M per hour storefront crawl to a halt at 12:03 AM on Black Friday because someone forgot to cache their hero images. The origin servers melted, the checkout queue backed up, and the team spent the whole weekend firefighting instead of counting sales. You don't need a massive engineering team to avoid that nightmare, but you do need a preparation checklist that starts in October, not the night before.

Lock Down Your Static Caching Before the Flood Hits

Back in 2019 I was on call for a mid-size fashion retailer who was convinced they were ready for Black Friday. They'd scaled their origin servers, they'd bought more CDN bandwidth, everything looked great on paper. What they'd missed was that their product images had a Cache-Control header of max-age=3600 - just one hour. So every hour, when thousands of shoppers were refreshing the same best-selling jacket page, tens of thousands of requests punched straight through to the origin. We fixed it in about ten minutes, but that ten minutes cost them a lot of frustrated customers.

Your static assets - images, product videos, CSS, JavaScript, fonts - shouldn't be touching your origin at all during peak shopping. For Black Friday peak shopping, you want them cached at the edge for days or even weeks. The HTTP Working Group Specifications define exactly how browsers and CDNs interpret caching headers, and getting this right is the single easiest win in your holiday preparation. For files that don't change often, use a long max-age with immutable so the browser doesn't even revalidate. If you version your files with a hash in the filename, like app.a3b4c5.js, you can cache them for a year without worry.

This is where your CDN Product Page Optimization: Sub-Second Loading for Higher Conversion Rates really pays off. A product page might load 40 images and 3 JavaScript bundles, and if even half of them aren't cached properly, that page feels slow under load. I always tell teams to run a quick audit in early October: open your top 20 product pages, check the response headers, and confirm your hit ratio is above 95% for static assets. If it isn't, you're leaving performance and origin protection on the table. Don't wait until your ecommerce readiness test fails at 2 AM on Friday.

# Ideal headers for versioned static assets (images, JS, CSS)
Cache-Control: public, max-age=31536000, immutable
CDN-Cache-Control: public, max-age=31536000
# For HTML product pages that change with inventory/price
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
# Verify with curl
curl -I https://yourstore.com/assets/product-123.jpg

Protect Dynamic Paths: Don't Cache What Shouldn't Be Cached

Here's the mistake I see almost every beginner make: they get excited about caching and try to cache everything, including the cart and checkout. I can't tell you how many times I've seen a shopper add a pair of shoes to their cart and then see someone else's cart contents because a well-meaning developer cached /cart at the edge. Dynamic, personalized content must bypass the cache completely. Your Black Friday CDN setup needs explicit rules that say, "If this URL has a cookie, a session, or is part of the buying process, go straight to the origin."

You need a clear allowlist and blocklist. Cache your product catalog pages, category pages, and marketing content aggressively. Never cache anything that involves personal data, inventory reservation, or payment. That includes /cart, /checkout/*, /my-account/*, and any API endpoint that returns user-specific JSON. According to the web.dev Articles on caching best practices, separating static and dynamic paths at the CDN layer is critical for both speed and correctness. This isn't just about performance, it's about not creating a privacy disaster during your biggest sales event.

Getting this right ties directly into your broader architecture. Good CDN Cart Session Management: Maintaining Shopping State Across Edge Nodes relies on cookies and edge logic to keep a shopper's state consistent, while CDN Checkout Flow Acceleration: Edge Optimization for the Revenue-Critical Path focuses on making that uncacheable path as fast as possible through techniques like TLS optimization, connection keep-alives, and Argo-style smart routing. You aren't trying to cache checkout - you're trying to accelerate it. I'll often create a single CDN rule that bypasses cache when a cart_id or session_token cookie is present, and that one rule has saved more Black Fridays than any amount of origin scaling.

# Example VCL / Edge Rule to bypass cache for dynamic e-commerce paths
if (req.url ~ "^/(cart|checkout|account|api/cart)" ) {
  return(pass); # Don't cache, go to origin
}
if (req.http.Cookie ~ "cart_id|session_token|shopify_cart") {
  return(pass); # Personalized request, bypass cache
}
# Everything else can use the normal cache logic
# For Cloudflare / Fastly / Akamai, create a Cache Rule:
# "Bypass Cache when URI Path contains /checkout OR Cookie contains cart_id"

Set Hard Performance Budgets and Alerts You'll Actually Use

In October, everything feels calm. Your dashboards are green. It's easy to say you'll watch the metrics on Black Friday. But at 1 AM when traffic is 15x normal, you don't want to be staring at a vague graph trying to decide if things are okay. You need hard numbers, set weeks in advance, with alerts that wake you up before customers notice. I learned this after a client spent three hours debating whether a 1.2 second TTFB was "bad enough" to roll back a change. We now set the budget before the holiday rush and treat it like a contract.

For beginner teams, keep it simple. You don't need twenty metrics. Focus on four that tell you if your CDN and origin are healthy under load. Your cache hit ratio tells you if your caching rules are working. Your time to first byte at the edge tells you if shoppers are feeling the speed. Your origin response time tells you if your servers are starting to strain. And your 5xx error rate tells you if customers are hitting dead ends. If you nail those four, you'll catch 90% of Black Friday failures in the first five minutes.

Set these budgets in your CDN analytics and your origin monitoring, and test your alerts before the peak. I have every team run a load test in late October that intentionally triggers these alerts - push the origin until response times climb, or purge the cache to watch the hit ratio dip. If your Slack or PagerDuty doesn't fire correctly during a test, it won't fire when it counts. Holiday preparation isn't just about making things fast; it's about making failures obvious and actionable.

Metric to Watch Black Friday Target Warning Threshold (Alert Me) Where to Check It
CDN Cache Hit Ratio (Static Assets) > 96% < 90% for 5 minutes CDN Dashboard > Caching Analytics
Edge TTFB (Product & Category Pages) < 150 ms (p75) > 350 ms (p75) for 3 minutes Real User Monitoring (RUM) + CDN logs
Origin Response Time < 400 ms (avg) > 800 ms (avg) for 3 minutes Origin APM / CDN Origin Status
HTTP 5xx Error Rate < 0.1% > 0.5% for 2 minutes CDN Error Logs + Status Page
Checkout API Latency (Uncached) < 600 ms (p95) > 1200 ms (p95) for 2 minutes Edge Performance & Origin Traces

Implement Origin Shielding and Stale-While-Revalidate Before You Need It

Here's where most stores fall apart on Black Friday: they’ve got decent TTLs but no plan for when the origin hiccups. You'll see traffic spike 8-12x in the first 15 minutes of a doorbuster, and if your origin takes even a 2-second latency hit, your edge hit ratio can collapse from 96% to under 60% in seconds. That’s not a caching problem — that’s a thundering herd problem. You need two things locked in *before* the flood: origin shielding and stale-while-revalidate.

Origin shielding isn’t optional at scale. Without it, every one of your 250+ PoPs can hammer your origin independently on a cache miss. With shielding, you collapse those misses to a single shield PoP — we typically see 85-90% reduction in origin requests during peak just from this one toggle. Pair that with stale-while-revalidate=60 and stale-if-error=86400. That way, if your inventory service stalls for 5 seconds, users still get a slightly stale product page in 25ms instead of a 504. For Black Friday, serving a page that’s 10 seconds old is infinitely better than serving no page at all.

Don't guess your TTLs — codify them. For static product images and JS, you want immutable long TTLs. For APIs, you need surgical precision. Our approach for high-velocity inventory endpoints is covered in CDN Inventory API Caching: Real-Time Stock Visibility with Aggressive TTLs, but the rule of thumb is: 1-2s TTL at the edge with SWR for inventory, 0s (bypass) for cart/checkout. Here's the battle-tested header config we deploy for most Shopify/Magento-plus-CDN stacks:

# Edge Cache Policy - Black Friday Ready
# Static Assets (images, fonts, hashed JS/CSS)
location ~* \.(jpg|jpeg|png|webp|avif|woff2|js|css)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    add_header CDN-Cache-Control "public, max-age=31536000";
    proxy_hide_header Set-Cookie;
}

# Inventory / Stock API - High churn, must not dogpile origin
location /api/inventory/ {
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    add_header Cache-Control "public, max-age=2, s-maxage=2, stale-while-revalidate=30, stale-if-error=86400";
    add_header Surrogate-Control "max-age=2, stale-while-revalidate=30";
}

# Dynamic - NEVER cache
location ~* ^/(cart|checkout|account|api/price) {
    add_header Cache-Control "private, no-store, max-age=0";
    add_header CDN-Cache-Control "no-store, bypass-cache";
}

Advanced Patterns: Taming Stampedes, Price Variants, and Experiment Drift

Once shielding and SWR are live, you'll hit the next tier of Black Friday failures: cache fragmentation and stampedes. If you're doing per-user pricing or geo-based promos, a naive cache key will either leak prices between users (disaster) or fragment your cache so badly your hit ratio drops to 20%. We've seen stores run Price Personalization at CDN Edge: Dynamic Pricing Without Origin Round-Trips logic that created 40,000 cache variants for a single SKU. The fix is to never cache personalized HTML. Instead, cache a single base page shell at the edge for 5-10 minutes and inject price via an ESI include or an edge worker fetch to a price API with a 1s TTL. You keep a 95%+ hit ratio on the heavy HTML while price stays real-time.

The other killer is the thundering herd on a hot SKU when stock drops from 500 to 12. Suddenly every edge node expires at the same second and slams your origin. You need proxy_cache_lock (or request coalescing / collapsed forwarding) enabled so only one request goes to origin while others wait ~500ms for the fresh copy. Combine that with jittered TTLs — instead of a flat 60s, use 55-65s randomly — so you don't get synchronized expiries across the fleet. If you're running edge experiments, be extra careful here. A/B tests that bucket at the edge can double your variants overnight.

That’s exactly why you should isolate your experiments. If you're running A/B Testing Product Pages at CDN Edge: Experimenting on Layout and Content, don’t use a cookie-based vary that busts cache. Use edge assignment with a Vary: X-Experiment-ID that only has 2 stable values (control/variant) and set it via a worker before the cache lookup, not after. Test it under load — we run a pre-BF load test at 3x projected peak RPS (usually 15k-25k RPS for mid-market) and measure p95 TTFB. If your p95 jumps over 350ms or origin 5xx exceeds 0.1% during the test, your cache keys or shielding aren't ready. Fix it now, not at 12:01 AM Friday.

Frequently Asked Questions

What’s a realistic edge hit ratio to target on Black Friday?

For a healthy e-commerce store, aim for 92-97% on cacheable traffic (static + product pages). If you’re below 88% during peak, you’re likely caching dynamic paths incorrectly or have over-fragmented keys from personalization. Shielding + SWR should keep origin RPS under 200 even at 20k edge RPS.

Should I purge my entire CDN cache right before the sale starts?

Absolutely not. A full purge guarantees a cold cache and a thundering herd the second your sale goes live. Instead, do a soft purge of only changed product collections 10-15 minutes early, and let stale-while-revalidate handle the rest. If you must invalidate, use surrogate key purging for surgical updates.

How do I cache inventory without showing “in stock” when it’s sold out?

Use a very short TTL (1-2 seconds) with background revalidation and stale-while-revalidate. You’ll serve at most 2 seconds of stale stock data, which customers tolerate far better than a 3-second spinner or error page. Never set inventory to 60s+ on hot SKUs — you’ll oversell and kill trust.

Can I run A/B tests during Black Friday without hurting performance?

You can, but keep it minimal. Limit to one lightweight layout test, assign buckets at the edge, and ensure your cache key only varies on the experiment ID. Avoid running more than two concurrent experiments or using client-side flicker-heavy tests — they’ll add 150-300ms of render delay when every millisecond costs conversions.

Related Articles

References & Standards: HTTP Working Group Specifications · web.dev Articles · IETF Datatracker