Do You Need a CDN or Just Better Caching
13 Oct 2026Most sites that think they need a CDN actually have a caching problem. A CDN moves bytes closer to the user. Caching avoids regenerating those bytes in the first place. If your origin is slow because it recomputes the same response on every request, a CDN just hides that latency for cached edges and exposes it in full on every miss.
Find out which problem you have
Check where the time actually goes.
curl -o /dev/null -s -w "dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com/
- High
time_connectrelative to total, and you’re serving users far from your origin: that’s distance. A CDN helps. - High gap between
time_connectandtime_starttransfer: your app is slow to generate the response. That’s a caching or compute problem. A CDN won’t fix it — it’ll just cache the slow response until it expires, then you eat the slowness again on every miss.
When better caching is the fix
- Your app re-renders the same page for every visitor with no
Cache-Controlheader. - Your database runs the same expensive query per request.
- Your API responses are identical for minutes or hours but get regenerated every time.
Fix this with HTTP caching headers first, before reaching for infrastructure:
Cache-Control: public, max-age=300, stale-while-revalidate=60
stale-while-revalidate lets you serve a slightly stale response instantly while refreshing it in the background. That alone kills most tail latency on read-heavy endpoints.
If you’re behind a reverse proxy already (nginx, Varnish, or your cloud LB), turn on response caching there before adding a new vendor.
When you actually need a CDN
- Your users are genuinely global and your origin is in one region.
- You serve static assets (images, JS, CSS, video) that benefit from edge presence regardless of caching correctness.
- You’re getting hit by traffic spikes that your origin can’t absorb even with caching, and you want the CDN to absorb the spike instead.
The trap: adding a CDN without fixing cache headers
If you drop Cloudflare or Fastly in front of an origin with no Cache-Control header, most CDNs default to not caching HTML at all. You pay for the extra network hop and get zero caching benefit. You’ll see this in the CDN’s own analytics: cache hit ratio near 0% on your main routes.
| Symptom | Real cause | Fix |
|---|---|---|
| Slow TTFB globally | No CDN, distant origin | Add CDN for static/cacheable routes |
| Slow TTFB even from nearby test | Slow app/DB | Fix caching or query, not distance |
| CDN added, no speedup | Missing Cache-Control |
Set headers before or alongside CDN |
| Fast first load, slow repeat | No client caching | Add max-age for assets |
The order that works
- Add correct
Cache-Controlheaders at your origin or reverse proxy. - Measure your actual cache hit ratio.
- Only then add a CDN, and only for the routes that benefit — static assets and cacheable pages, not personalized or write-heavy endpoints.
A CDN in front of a badly-cached origin is a more expensive way to serve the same slow page.