GH GambleHub

CDN and edge caching

CDN and edge caching

1) Objectives

CDN (Content Delivery Network) reduces latency and load on origin: caches static and conditionally dynamic content on edge nodes, provides scale, stability and security (DDoS/WAF), adds edge logic (rewriting responses/requests, authentication, A/B).

2) Cache model and keys

Ключ кеша = `scheme + host + path +?(selected query params) + headers (Vary)`

Recommended:
  • Normalize query ('utm _' exclude, leave 'v', 'lang', 'country', etc.).
  • Minimize'Vary '(for example,' Vary: Accept-Encoding, Accept-Language '), avoid' Vary: '.
  • For API - key from route + version identifier (semver, hash, build id) + necessary query/headers (for example, 'X-Tenant').
  • For personalized pages - edge-segmentation (by cookie/geo) or Skip-Cache.

3) TTL policies and headers

Base headings:
  • `Cache-Control: public, max-age=300, s-maxage=3600, stale-while-revalidate=60, stale-if-error=300`
  • 'Surrogate-Control '(if supported) is a separate policy for CDNs other than the browser.
  • 'ETag '/' Last-Modified '- conditional requests (304) and traffic savings.
  • For private: 'Cache-Control: private, no-store', if not cached.
  • APIs that allow cache: 'Cache-Control: public, s-maxage = 60' + version key.

Recommended approach: "eternal" resources (with fingerprint in the file name) → 'max-age = 31536000, immutable'; "pages/JSON" → short TTL + SWR.

4) Disability: purge/soft-purge

Purge by URL: pointwise.
Purge by tag/key: group purges (use 'Surrogate-Key: products: 42 category: food').
Soft-purge: marks content "outdated," edge gives stale until a new version is received.
"Warm" warming up: after the deploy, pull the main pages from the regions.

5) Edge performance patterns

Stale-While-Revalidate: quick response with "outdated" copy + background update.
Prefetch of critical resources (preload, preconnect, dns-prefetch).
Compression: gzip/br (for text), zstd if CDN is supported.
HTTP/2/3 (QUIC): multiplexing and less latency.
TLS session resumption and OCSP stapling on the perimeter.

6) Images and videos

Image optimization at edge: resize/format negotiation (`Accept: image/avif,webp`), авто-WebP/AVIF, DPR-варианты.
Lazy-load и responsive (`srcset`, `sizes`).
Video: HLS/DASH, fragmented MP4, origin-shield (central cache) to reduce storms.
Thumbnail services and signed URLs for private images.

7) Perimeter security

WAF: OWASP rules, country/ASN blocking, rate-limits with key (IP + cookie + token).
DDoS: L3/4 scrubbing, L7 checkers, JS challenges/turnstile.
Signed URLs/cookies for private resources (video/reports): TTL + HMAC/EdDSA.
Geo-fencing and compliance (for example, banning regions).

8) Edge-compute (logic at the edge)

Cases:
  • Personalization without breaking cache: segments (A/B), geo, language on edge, and content is cached.
  • Rewriting answers/titles, redirects, AB splits.
  • Token-based authentication: JWT signature verification, key binding.
  • Canary by cookie/percent: part of the traffic to the new backend.

Examples of technology include Cloudflare Workers/Durable Objects, Fastly Compute @ Edge, AWS Lambda @ Edge.

9) Multi-CDN and global perimeter

Reasons: coverage, SLA, cost, regional restrictions, isolation of incidents.
GSLB/Traffic Steering: on geo/latency/real errors; health-checks from multiple vantage points.
Single key/header scheme (Surrogate-Key), synchronized purge rules.
Origin-shield is common to all CDNs so as not to "hit" origin with disabilities.

10) Logging and metrics

Collect:
  • Hit ratio (cache, CDN → edge/origin), byte hit ratio.
  • Latency p50/p95/p99, error-rate by code/route.
  • Origin fetches: RPS/bytes/errors (protection against redundant misses).
  • Regional charts (by POP/ASN/country).
  • Integrate with Observability: Prometheus (pull via exporters), Grafana/OTel (push from edge logs).

11) SEO и SPA/SSR

SEO pages with SWR and short TTL are fast and fresh.
Sitemap/robots - we cache for a long time, but allow soft-purge.
Service Worker: offline caching, prefetch of critical paths, targeted updates.

12) Sample configurations and headers

12. 1 Cache-Control profiles

Static with fingerprint:

Cache-Control: public, max-age=31536000, immutable
HTML/SSR:

Cache-Control: public, max-age=60, s-maxage=600, stale-while-revalidate=60, stale-if-error=600
Surrogate-Control: max-age=600, stale-while-revalidate=120
API (cached storefront):

Cache-Control: public, s-maxage=60
Vary: Accept-Encoding

12. 2 NGINX (origin) - query/headers normalization

nginx map $arg_utm_source $utm_skip { default 1; "" 0; }
map $args $normalized_args {
default "";
"~(^    &)v=([a-z0-9]+)(&    $)" "v=$2";
}
proxy_cache_key "$scheme://$host$request_uri?$normalized_args";
add_header Surrogate-Key "product:{{id}} category:{{cat}}";

12. 3 Fastly VCL - soft-purge and keys

vcl sub vcl_recv {
set req. hash += req. http. host req. url. path;
set req. hash += querystring. decode(req. url, "v,lang");
if (req. method == "PURGE") {
if (req. http. Fastly-Soft-Purge) { softpurge; } else { purge; }
return (synth(200, "purged"));
}
}
sub vcl_deliver {
set resp. http. Surrogate-Key = "product:42 category:food";
}

12. 4 Cloudflare Workers - Signed URLs

js export default {
async fetch(req, env) {
const url = new URL(req. url);
if (url. pathname. startsWith("/private/")) {
const token = url. searchParams. get("token");
if (!token! verify(token, env. SIGNING_KEY)) return new Response("Forbidden", { status: 403 });
}
return fetch(req);
}
}

12. 5 Lambda @ Edge - Geo Options

js exports. handler = async (event) => {
const req = event. Records[0].cf. request;
const country = req. headers['cloudfront-viewer-country']?.[0]?.value          'US';
if (country === 'DE') req. headers['accept-language'] = [{ key:'Accept-Language', value:'de' }];
return req;
};

13) Private data and API

Never cache private responses without key isolation (per-user/per-token).
Use Signed Cookies/Headers and'Vary: Authorization'only with strict control (otherwise - cache-bust).
Safe alternative: separate the public layer (cached) and private inclusions (ESI/edge composition).

14) Geo/content rules

Licensing restrictions: geo-deny on edge, placeholders instead of blocking origin.
Age/regulatory banners - render on edge (do not punch cache).

15) Anti-patterns

'no-cache, no-store'for the entire site → loss of CDN effect.
'Vary'on unstable headers (for example,' User-Agent ') → cardinality.
Clear the entire cache on each release.
Short TTLs without SWR → storm to origin.
Personal pages are cached without segmentation/token keys.
Lack of origin-shield → multiple parallel misses.

16) Implementation checklist (0-45 days)

0-10 days

Categorize resources: immutable/HTML/API.
Enable gzip/br, HTTP/2/3, query normalization, 'Surrogate-Key'.
Enter SWR/IFE and base purge.

11-25 days

Edge-image optimization (resize/format), origin-shield.
Signed URLs for private media, WAF/DDoS profiles.
Dashboards: hit ratio, origin fetches, p95 by POP.

26-45 days

Multi-CDN or GSLB strategy, canary weights on the perimeter.
Edge-compute for segmentation/AB/geo, soft-purge by keys.
Auto-warming and purge integration in CI/CD.

17) Maturity metrics

Byte hit ratio ≥ 85% for static, ≥ 60% for HTML/conditional dynamics.
Origin RPS stable at peaks (no "storms").
p95 TTFB reduced by ≥ 30% across major regions.
% of stale responses for incidents> 90% (user barely noticed).
Complete automation of purge keys in release pipelines.

18) Conclusion

The effective CDN circuit is keys/TTL/options, disability discipline, and edge logic. Add SWR/IFE, origin-shield, media optimization, and strong security (WAF, signed URLs). Standardize metrics and integrate purge into CI/CD - and you get a fast, economical and stable perimeter, ready for peak loads and black swans.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Telegram
@Gamble_GC
Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.