Concept · Caching

CDN vs Application Cache

01

Why this matters

Both are caches. Both reduce load on your origin. They live at different layers of the stack, cache different things, and solve different problems. A candidate who says "we'll use a cache" and can't distinguish them is punting on an important design choice.

02

The layers of the cache sandwich

Going from user to database, cache opportunities exist at every layer:

  1. Browser cache — the user's own device. Free, zero latency, tiny.
  2. CDN (edge)CDN PoPs close to the user. Shared across all users in that geography.
  3. Reverse proxy — Nginx / Varnish in your datacenter, caches responses from your app.
  4. Application cache — Redis / Memcached inside your services.
  5. Database buffer pool — Postgres / MySQL's own in-memory cache of hot pages.

Each layer catches what the layer above missed. A request that hits the browser cache costs nothing. A request that misses everything and hits disk is thousands of times more expensive.

03

CDN vs application cache — the honest comparison

AspectCDNApplication cache (Redis)
Location~300 PoPs globallyYour datacenters
StoresHTTP responses — static assets, public API responsesArbitrary structured data — sessions, counters, computed results
Latency to user~10–50ms (near edge)App server → Redis: 1–3ms, then network to user
Cache keyURL + varied headersArbitrary keys
InvalidationAPI purge or versioned URLsDEL key
Who runs itCloudflare / AWS / AkamaiYou
Cost modelPer-request + bandwidthPer-GB memory per hour
Best forPublic, cacheable, geographically distributed readsPrivate, compute-expensive, per-user data
04

Use each for what it's good at

CDN wins for: images, JavaScript bundles, CSS, fonts, public API responses (leaderboards, product catalogs), video segments. Anything where the same bytes get sent to thousands of users. The CDN absorbs the fan-out so your origin doesn't.

App cache wins for: per-user sessions, personalized feeds, rate-limit counters, hot DB rows, precomputed aggregations, leaderboard state (writes fast, reads fast). Anything that's per-user or frequently mutated.

The mistake: trying to put per-user data behind a CDN. Cache hit rate ≈ 0 (each user is unique). You pay CDN cost for no benefit. Put per-user data in app-level cache close to your backend.

05

Deep dive — stacking them

They're not alternatives — they stack. A well-designed page uses both:

  • Static assets (CSS, JS, images) → CDN with long TTL + versioned URLs. Near-100% hit rate.
  • Public HTML for logged-out users → CDN with short TTL (5 min). 90%+ hit rate.
  • Logged-in HTML → bypass CDN, render at origin. Fetch user data from Redis (app cache). 95%+ Redis hit rate.
  • Per-user feed data → Redis sorted sets, keyed by user ID.
  • Hot DB rows (user profile) → Redis cache-aside, TTL 5 min. Feed renderer reads from Redis, DB on miss.

Your origin sees < 5% of total traffic. Of that, 90%+ is served from Redis. Your database sees < 1%. This is what scaling looks like.

The hit rate ladder

Browser cache catches 20%. CDN catches 60% of what's left. App cache catches 90% of what's left. DB sees ~3%. Disk reads are rare events.

06

Real-world

Netflix

CDN for video, EVCache for session

Video segments on Open Connect (their own CDN). EVCache (Netflix's Memcached variant) for session, profile, recommendations.

Shopify

Cloudflare + Redis

Storefront HTML + assets through Cloudflare. Cart, session, inventory counts in Redis. Two-layer defense against the DB.

New York Times

Fastly for articles

Article HTML cached at Fastly with 2-min TTL. Breaking news flushes the cache via API. Origin sees < 1% of reads.

Stripe

No CDN; heavy app cache

Every response is per-merchant, per-account — no CDN benefit. Aggressive Redis caching of hot rows. Origin sees every request but serves fast.

07

Used in problems

URL shortener: CDN caches redirects for top URLs (shared across users). News feed: Redis for per-user feed; CDN for static assets. YouTube/Netflix: CDN absolutely critical for video; Redis for session/personalization.

Next up