Infrastructure · Performance
How to Configure a CDN: DNS, Cache Rules, TLS, and Purging Done Right
Configuring a CDN comes down to five steps: point your DNS at the edge, set caching rules per content type, secure the connection end to end with TLS, handle cache invalidation, and verify it’s working. You route traffic by creating a CNAME from a subdomain like cdn.example.com to the provider’s edge hostname, then control caching with Cache-Control headers — long, immutable TTLs for static assets, short or no caching for dynamic content and APIs. The most important habit is versioning static assets with a content hash in the filename so you can cache them for a year yet still push instant updates, rather than relying on mass purges that stampede your origin. Use full end-to-end TLS, enable an origin shield to absorb bursts, and verify with a curl that shows an X-Cache HIT header. Done right, a CDN cuts latency dramatically; done wrong, it serves stale or even leaked content.
Key takeaways
- Five steps: DNS, cache rules, TLS, purging, verify. The order matters and each has its own pitfalls.
- Cache by content type. Long immutable TTLs for static assets; short or no caching for dynamic and APIs.
- Version assets, don’t mass-purge. A content hash in the filename gives instant updates without stampeding the origin.
- Use end-to-end TLS and an origin shield. Encrypt to the origin and add a mid-tier cache to absorb bursts.
- Verify with cache headers. An X-Cache HIT confirms the edge is serving; watch your hit ratio over time.
A content delivery network can transform site speed by serving content from edge servers close to your users — or it can quietly serve stale pages, leak one user’s data to another, and overload your origin if you misconfigure it. The difference is entirely in the setup. This guide walks the configuration step by step: DNS routing, caching rules, TLS, invalidation, and verification, with the specific headers and habits that separate a fast, safe CDN from a broken one.
How does a CDN actually work?
Before configuring anything, it helps to picture the request flow, because every setting you choose shapes one part of it. When a user requests content, the nearest CDN edge server checks its cache. If a fresh copy exists — a cache hit — it returns immediately, with no trip to your origin. If not — a cache miss — the edge fetches from your origin server (ideally through an origin shield), caches the result according to your rules, and serves it. Every subsequent request for that object within its lifetime is served from the edge. The diagram shows the path.
The whole point is to maximise the proportion of requests answered at the edge — the cache hit ratio — so that your origin sees only misses and revalidations. A well-configured CDN lifts that ratio from a mediocre 60 percent toward 90 percent or higher, which both speeds up users and slashes origin load. Almost everything that follows is about pushing more requests into the hit column without ever serving content that should have been fresh.
Step one: pointing DNS at the edge
The first configuration step is routing your traffic through the CDN via DNS. The cleanest approach is to use a dedicated subdomain for CDN-served assets — something like cdn.example.com — and create a CNAME record pointing it to the provider’s edge hostname, such as customer123.edgeprovider.net. Using a subdomain sidesteps a real limitation: the apex or root domain often can’t take a CNAME, so if you must serve the apex through the CDN you’ll need your DNS provider’s ANAME or ALIAS record support, or a proxy arrangement.
Two details make this step go smoothly. First, set a sensible DNS TTL — a low value of 60 to 300 seconds gives you failover flexibility, letting you reroute quickly if something breaks, at a small cost to resolution caching. Second, some providers require domain-ownership validation via a temporary TXT or CNAME record before they’ll serve your hostname, so expect that handshake. Once DNS resolves to the edge, traffic flows through the CDN, but nothing is cached usefully until you set the rules — which is the step that actually determines performance.
Step two: cache rules by content type
Caching behaviour is the single most impactful part of the configuration, and it’s driven by Cache-Control headers your origin sends. The core principle is to cache by content type, because different content has wildly different freshness needs. Static assets that never change once deployed — versioned CSS, JavaScript, images, fonts — should be cached as aggressively as possible. Dynamic, personalised, or API responses should be cached briefly or not at all. The table shows sensible defaults.
| Content type | Cache-Control | Why |
|---|---|---|
| Static assets | public, max-age=31536000, immutable | Never changes once versioned |
| HTML pages | public, max-age=3600, must-revalidate | Changes occasionally |
| Semi-static | s-maxage=300, stale-while-revalidate | Fresh-ish, fast, no stalls |
| API / personalized | private, no-store | Must never be shared |
A few directives deserve precision. The s-maxage value sets how long the CDN caches and overrides max-age, which governs the browser, so you can cache long at the edge while letting browsers revalidate sooner; public allows both CDN and browser to cache, while private restricts to the browser only. Use the Vary header carefully — Vary: Accept-Encoding is fine, but Vary: User-Agent or Vary: Cookie explodes your cache into a near-unique entry per visitor and destroys your hit ratio. And never cache a response carrying Set-Cookie, or you risk serving one user’s session to another.
Which content should you cache?
Beyond the header mechanics, it helps to think in terms of content classes and the strategy each calls for, because the right approach differs sharply across them. Static assets — your versioned CSS, JavaScript, images, and fonts — are the easy win: cache them aggressively with long, immutable TTLs, since they never change once deployed. A static or mostly-static HTML site can push almost everything to the edge and keep its origin nearly idle. This is where a CDN delivers its biggest, simplest gains.
Dynamic and media content need more nuance. Personalised pages and API responses should generally bypass the cache or use very short TTLs, and where you do cache personalised content, you scope it carefully with cache keys that include only the headers that matter — never the full cookie. Large media like video benefits from segmented delivery, signed URLs for access control, and an origin shield to spare the origin. A common pattern is the hybrid: serve static assets through the CDN on one subdomain while routing dynamic endpoints directly to your origin on another, so each class of content gets the handling it needs rather than forcing one policy across all of them.
Step three: securing TLS to the origin
Security configuration centres on encrypting the connection all the way through, not just to the edge. You want full end-to-end TLS, where the CDN fetches from your origin over HTTPS — the “Full” or “Full (Strict)” modes most providers offer — rather than terminating encryption at the edge and talking to your origin in plaintext. That requires a valid certificate on your origin matching the hostname the CDN uses to reach it, or the provider’s origin-certificate feature where available. Aim for TLS 1.3 with strong ciphers throughout.
Two modern enablements belong in this step. Turn on HTTP/2 and HTTP/3 — the latter built on QUIC — wherever the CDN supports them, since both reduce latency for pages loading many concurrent resources, which is most pages. And handle HSTS deliberately: it’s worth enabling to force HTTPS, but a too-aggressive max-age applied globally is hard to walk back, so test it in staging before rolling it out. Getting the certificate and Host-header handling right is also where many setups break, producing TLS errors or cache misses that the verification step is designed to catch.
Step four: invalidation without stampedes
Keeping the cache fresh when content changes is where CDNs cause the most self-inflicted pain, and the key insight is to avoid mass purges almost entirely. The elegant solution for static assets is versioning: embed a content hash in the filename or query string, so a changed file becomes a new URL — main.7a9c1f.js becomes main.b2e8d0.js — which means you can cache each version for a full year as immutable while new deployments propagate instantly, because the URL itself changes. This sidesteps invalidation completely for the bulk of your assets.
When you do need to purge, do it surgically. Most providers support purging a single URL, a wildcard prefix, or — best for groups — surrogate keys or cache tags that let you invalidate related objects atomically. The one thing to avoid is the global “purge everything” during traffic, because clearing every edge simultaneously triggers a cache stampede: all edges miss at once and hammer your origin together. Stagger TTLs, prefer tag-based or soft purges, schedule bulk invalidations for low-traffic windows, and automate purges through the CDN’s API in your deployment pipeline so they happen reliably and surgically.
What are the common pitfalls?
Most CDN problems cluster into a handful of recurring mistakes, and recognising them in advance saves a lot of debugging. The most dangerous is caching content that should be private — if a response carrying a session cookie gets cached, the edge can serve one user’s data to another, a genuine security incident rather than a mere performance bug. The fix is to ensure authenticated routes return private, no-store and to keep cookies out of the cache key. Close behind is the Vary explosion, where varying on User-Agent or Cookie shatters your cache into near-unique entries and collapses your hit ratio.
The other frequent failures are infrastructural. SSL mismatches — a certificate that doesn’t match the hostname the CDN uses, or a missing intermediate chain — produce TLS errors that block delivery entirely. Host-header misconfiguration sends your origin the wrong virtual host, so it serves the wrong site or none at all. And cache-header mistakes, like forgetting to set Cache-Control on static assets, leave the edge guessing and often defaulting to no caching. When something’s wrong, the diagnostic loop is straightforward: use curl with verbose flags, dig, and traceroute to isolate whether the problem lives in DNS, TLS, the cache headers, or the origin — and the verification step exists precisely to catch these before they reach users.
Step five: protecting and verifying the origin
The final pieces protect your origin and confirm the whole setup works. An origin shield — a designated mid-tier regional cache sitting between the edge servers and your origin — collapses the many edge requests during a global burst into far fewer origin fetches, which is the main defence against the stampedes that purges and new rollouts can cause. Pair it with origin keep-alive, HTTP/2 between CDN and origin, and conditional requests using If-Modified-Since or If-None-Match so unchanged assets revalidate cheaply without re-transferring. Resilience directives help too: stale-while-revalidate serves slightly stale content while fetching fresh in the background, and stale-if-error keeps you up when the origin briefly fails.
Verification is quick but essential. The terminal shows the checks.
$ curl -I https://cdn.example.com/static/app.7a9c1f.js HTTP/3 200 cache-control: public, max-age=31536000, immutable x-cache: HIT # served from the edge age: 842 # seconds since cached # First request may show MISS; second should be HIT. $ curl -I https://cdn.example.com/api/me # should NOT be cached cache-control: private, no-store # Then watch hit ratio, origin RPS, P95 latency, cert expiry alerts.
A first request often shows a MISS while the edge populates; the second should show HIT with an Age header counting up. Beyond the spot check, set up ongoing monitoring of the metrics that matter — cache hit ratio, origin requests per second, egress bandwidth, and P95 and P99 latency — and configure alerts for certificate expiry and origin health, since a silently expired cert or an unhealthy origin can take a site down even with a perfect cache. This continuous observation is part of the same discipline our server monitoring guide covers, and the broader strategic picture of when and why to use a CDN is laid out in our CDN guide. For teams running a fast origin behind that edge, our dedicated servers in Toronto give the responsive, well-provisioned backend a CDN amplifies rather than masks — while correct cache headers and versioning are what actually keep the edge doing its job.
What does a CDN cost?
It’s worth understanding the cost model before you commit, because a CDN’s pricing can surprise you in two directions. The main charge is egress bandwidth — the data served from the edge to users — typically billed per gigabyte on a tiered scale that runs roughly from a couple of cents to over ten cents per gigabyte depending on the provider and region. For a text-and-image site this is modest, but for video or large downloads it adds up quickly, which is one reason media delivery warrants careful caching to keep repeat fetches off the origin.
The less obvious costs are worth checking too. Some providers charge per request, and several bill for cache invalidations — per purge or per object — which is another reason the versioning-over-purging discipline saves money as well as origin load. When evaluating providers, weigh the egress and request pricing against your actual traffic pattern, factor in any per-purge fees, and note that some lower their transfer costs if you also use their DNS. The honest framing is that a CDN almost always pays for itself in reduced origin bandwidth and faster pages, but only if you’ve configured caching well enough to keep your hit ratio high — a poorly configured CDN can cost more in egress while delivering little of the benefit.