We run a content site with images and articles, and read traffic is mostly global. How would you use a CDN and edge caching to cut latency and origin load, and what content can't be cached that way?
system-design · Mid level · software-engineering
What the interviewer is really asking
Assesses understanding of CDN/edge caching specifically — cache-control semantics, static vs dynamic/personalized content, and edge invalidation — distinct from an application-tier key-value cache like Redis.
What to say
- Push static and cacheable content to the CDN edge: serve images, CSS/JS, and stable article HTML from edge POPs near the user, driven by explicit Cache-Control headers (long max-age for immutable assets, shorter TTLs or stale-while-revalidate for content that changes).
- Use content-hashed/versioned asset URLs so you can set effectively-immutable caching and never serve a stale asset — a new deploy ships new URLs rather than fighting cache invalidation; reserve explicit edge invalidation for the cases versioning can't cover.
- Be explicit about what doesn't cache at the edge: per-user personalized responses, authenticated content, and anything with a Set-Cookie or short-lived data — route those to the origin (or cache fragments / use edge compute carefully), and split the page so the static shell is cached while the personalized parts load separately.
What to avoid
- Treating the CDN as interchangeable with an application cache like Redis and conflating object-key lookups with edge HTTP caching.
- Caching personalized or authenticated responses at a shared edge, leaking one user's content to another.
- Relying solely on manual cache purges for every change instead of versioned URLs, so deploys are slow and error-prone and stale assets slip through.
Example answers
Strong: Reads are global, so I'd put a CDN at the edge for everything cacheable: images, JS/CSS, and stable article pages, served from POPs near each user. I'd drive it with Cache-Control — immutable hashed asset URLs get a year-long max-age, article HTML gets a shorter TTL with stale-while-revalidate so a refresh is invisible to users. Content-hashed filenames mean a deploy publishes new URLs, so I rarely need to purge. What I won't edge-cache is anything personalized or authenticated — the logged-in header, recommendations, account pages — those skip the shared cache. I'd split the page so the cacheable shell is at the edge and the personalized bits hydrate from the origin.
Weak: I'd put a CDN in front of the whole site and cache every response so everything is fast everywhere.