A CDN only moves the needle when the shared cache can store a shareable response under a stable key. Split TTL by content class: short s-maxage for HTML and other shells that change every deploy, and long immutable lifetimes for content-hashed JS, CSS, and media. Keep Cookie, Authorization, and unbounded query parameters out of the public key; forward only the few parameters that truly change the bytes. Load balancers and reverse proxies in front of origin should honour the same Cache-Control story so an edge HIT is not undone by a mid-tier that re-keys on viewer-specific headers.
Ops prove-out before widening TTL: hit the same Host and path twice from a clean client and compare Age and X-Cache with the Cache-Control the edge actually returned. After a deploy, purge or version the shell and confirm hashed assets still HIT while the document rematerialises. If misses stay flat after a purge, the key still includes something viewer-specific — lengthening TTL alone will not cut origin traffic or TTFB in production.