Tutorial

CDN Explained: How Content Delivery Networks Work

June 06, 2026

Back to Blog
Managing servers the hard way? Panelica gives you isolated hosting, built-in Docker and AI-assisted management.
Start free

What Is a Content Delivery Network?

A Content Delivery Network (CDN) is a geographically distributed network of servers that delivers web content from locations physically close to the user requesting it. Without a CDN, every request travels to your origin server — which might be in Frankfurt, Germany, while your visitor is in Sydney, Australia. That is approximately 16,000 kilometers of network hops, adding 200-300 milliseconds of latency just from the speed of light through fiber optic cables.

With a CDN, that same request is served from a Point of Presence (PoP) in Sydney, reducing latency to 5-20 milliseconds. The CDN stores a cached copy of your content at each edge location and serves it directly to nearby users. The result is dramatically faster page loads, reduced origin server load, improved reliability through redundancy, and built-in DDoS protection.

In this guide, we will break down exactly how CDNs work, how to configure the most popular providers, and the technical details of cache control that determine how effectively your CDN performs.

User Request
Sydney, AU
DNS Resolution
Anycast routing
Nearest PoP
Sydney edge
Cache Check
HIT or MISS
Serve Content
< 20ms latency

How Edge Caching Works

Edge caching is the core mechanism of every CDN. When a user requests a resource that has never been requested through that specific edge server before, the CDN fetches it from your origin server, stores a copy, and serves it to the user. All subsequent requests for the same resource at that edge location are served directly from cache — no trip to the origin required.

Cache HIT vs Cache MISS

Cache MISS (First Request)

User
Edge PoP
Origin Server

The edge server does not have the content cached. It fetches from origin, stores a copy, and serves to the user. Total latency: 200-500ms (origin + edge).

Cache HIT (Subsequent Requests)

User
Edge PoP

The edge server has the content cached. It serves directly without contacting origin. Total latency: 5-20ms. This is where the real performance gain happens.

# Check CDN cache status with curl
$ curl -sI https://example.com/style.css | grep -i "cf-cache-status\|x-cache\|age"
cf-cache-status: HIT
age: 3847

# First request (MISS)
$ curl -sI https://example.com/new-page.html | grep cf-cache-status
cf-cache-status: MISS

# Second request (HIT - now cached)
$ curl -sI https://example.com/new-page.html | grep cf-cache-status
cf-cache-status: HIT

Anycast DNS Routing

CDNs use Anycast DNS routing to direct users to their nearest edge server. In traditional (unicast) DNS, a domain resolves to a single IP address, and all users connect to that one server. With Anycast, the same IP address is announced from multiple locations worldwide. When a user makes a DNS query, the internet's BGP routing protocol automatically directs the request to the geographically nearest server announcing that IP.

How Anycast Works: Imagine the IP address 104.16.132.229 is announced by CDN servers in New York, London, Tokyo, and Sydney simultaneously. When a user in Tokyo makes a request, BGP routing sends it to the Tokyo server because it has the fewest network hops. The user never needs to know which server they are connecting to — the routing happens transparently at the network level.

Cache-Control Headers: The Complete Guide

The Cache-Control HTTP header is how your origin server tells the CDN (and browsers) how to cache each response. Getting these headers right is the difference between a CDN that saves 95% of your origin traffic and one that barely helps.

DirectiveWho It AffectsWhat It Does
publicCDN + BrowserResponse can be cached by any cache, including CDN edge servers
privateBrowser onlyResponse can only be cached in the user's browser, not by CDN
max-age=NCDN + BrowserCache is valid for N seconds from the time of the request
s-maxage=NCDN onlyOverrides max-age for shared caches (CDN). Browser ignores this.
no-cacheCDN + BrowserMust revalidate with origin before serving (NOT "do not cache")
no-storeCDN + BrowserDo not cache the response at all. Use for sensitive data.
immutableBrowserResource will never change. Browser skips revalidation even on reload.
stale-while-revalidate=NCDN + BrowserServe stale content for N seconds while fetching a fresh version in the background
Common Confusion: no-cache Does NOT Mean "Do Not Cache." The name is misleading. no-cache means "cache it, but always check with the origin before serving." To truly prevent caching, use no-store. Many developers use no-cache thinking it prevents caching, then wonder why their CDN is still serving cached content.

Recommended Cache-Control by Content Type

# Nginx cache headers by content type

# Static assets with hash in filename (main.a1b2c3.js)
location ~* \.(js|css)$ {
  add_header Cache-Control "public, max-age=31536000, immutable";
}

# Images (might be updated, 6-month cache)
location ~* \.(jpg|jpeg|png|gif|webp|avif|svg|ico)$ {
  add_header Cache-Control "public, max-age=15552000";
}

# Fonts (rarely change, 1-year cache)
location ~* \.(woff2?|ttf|eot|otf)$ {
  add_header Cache-Control "public, max-age=31536000, immutable";
}

# HTML pages (short cache with background revalidation)
location ~* \.html$ {
  add_header Cache-Control "public, max-age=300, s-maxage=3600, stale-while-revalidate=86400";
}

# API responses (private, no CDN caching)
location /api/ {
  add_header Cache-Control "private, no-cache, no-store";
}

Cache Invalidation Strategies

The hardest part of CDN caching is knowing when to invalidate cached content. Phil Karlton famously said, "There are only two hard things in Computer Science: cache invalidation and naming things." Here are the practical strategies:

Cache Purging

Manually tell the CDN to delete specific cached resources. All major CDNs offer purge APIs. Cloudflare allows purging by URL, tag, or entire zone. Use when content changes are infrequent and you need immediate updates.

Cache Busting (Versioning)

Append a version string or hash to the filename: style.v3.css or app.a1b2c3.js. Since the URL changes, the CDN treats it as a completely new resource. The most reliable approach for static assets.

Short TTL + Stale-While-Revalidate

Set a short max-age (5 minutes) with a long stale-while-revalidate (24 hours). Users always get fast responses (served from cache), but the CDN checks for updates every 5 minutes in the background.

Cache Tags (Surrogate Keys)

Tag cached responses with identifiers (e.g., product-123, category-shoes). When a product changes, purge all resources tagged with that product ID. Available on Fastly, Cloudflare Enterprise, and Varnish.

Setting Up Cloudflare (Free Tier)

Cloudflare is the most widely used CDN, and its free tier is remarkably generous. Here is a complete setup guide:

1
Add your site to Cloudflare. Sign up at cloudflare.com, enter your domain name, and select the Free plan. Cloudflare will scan your existing DNS records and import them automatically.
2
Update your nameservers. Change your domain registrar's nameservers to the ones Cloudflare provides (e.g., ava.ns.cloudflare.com and lee.ns.cloudflare.com). Propagation takes 1-24 hours.
3
Configure SSL mode. Set SSL/TLS to "Full (strict)" if your origin has a valid SSL certificate. This ensures end-to-end encryption. Never use "Flexible" — it sends traffic to your origin over HTTP, creating a security risk.
4
Enable caching features. Turn on Auto Minify for HTML, CSS, and JS. Enable Brotli compression. Set Browser Cache TTL to "Respect Existing Headers" to use your origin's Cache-Control headers.
5
Create Page Rules for dynamic content. For static sites or blog posts, create a page rule to "Cache Everything" — by default, Cloudflare only caches static file extensions.
# Cloudflare API: Purge specific URLs
$ curl -X POST \
  "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  -d '{"files":["https://example.com/style.css","https://example.com/logo.png"]}'
{"success":true,"result":{"id":"abc123"}}

# Purge everything (use sparingly)
$ curl -X POST \
  "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -d '{"purge_everything":true}'

BunnyCDN: The Developer-Friendly Alternative

BunnyCDN is a popular alternative to Cloudflare, especially for developers who want simple pricing and excellent performance. It uses a pull zone model where you point BunnyCDN at your origin, and it caches content automatically.

# BunnyCDN API: Purge cache
$ curl -X POST \
  "https://api.bunny.net/pullzone/{pull_zone_id}/purgeCache" \
  -H "AccessKey: {api_key}"
{"HttpCode":200,"Message":"OK"}

# Purge specific URL
$ curl -X POST \
  "https://api.bunny.net/purge?url=https://cdn.example.com/style.css" \
  -H "AccessKey: {api_key}"
FeatureCloudflare FreeBunnyCDNKeyCDN
PricingFree$0.01/GB (pay-as-you-go)$0.04/GB (min $4/month)
Global PoPs310+114+60+
DNS managementIncludedSeparate serviceNo
DDoS protectionIncludedBasicBasic
Image optimizationPro plan onlyIncludedNo
WebP/AVIF auto-convertPolish (Pro)OptimizerNo
Custom SSLFreeFree (Let's Encrypt)Free (Let's Encrypt)
Real-time analyticsYesYesYes

Origin Shield: Protecting Your Server

Origin Shield is a CDN feature that adds an extra caching layer between your edge PoPs and your origin server. Without Origin Shield, if your content expires in 100 different PoPs simultaneously, your origin receives 100 requests. With Origin Shield, only the shield server contacts your origin — the 100 PoPs fetch from the shield instead.

100 Edge PoPs
Cache expired
Origin Shield
Single layer
Origin Server
1 request only
When Origin Shield Matters Most: If your origin server has limited capacity, is on shared hosting, or generates dynamic content that is computationally expensive, Origin Shield dramatically reduces origin load. It is especially valuable during traffic spikes — instead of 10,000 simultaneous cache misses hitting your server, the shield absorbs them.

HTTPS with CDN

Running HTTPS through a CDN involves three connection segments, each with its own encryption:

SegmentEncryptionCertificate
User → CDN EdgeTLS 1.2/1.3CDN's certificate (or your custom cert)
CDN Edge → Origin ShieldTLS (internal)CDN's internal certificates
CDN/Shield → OriginTLS (Full Strict)Your origin's certificate (Let's Encrypt, etc.)
Never Use "Flexible" SSL Mode. In Flexible mode, the CDN terminates SSL and connects to your origin over plain HTTP. This means your data travels unencrypted between the CDN and your server. Anyone on that network path can intercept it. Always use "Full" or "Full (Strict)" mode with a valid origin certificate.

CDN for Dynamic Content

CDNs are not just for static files. Modern CDNs can accelerate dynamic content too, though the strategies differ:

Short-TTL Caching

Cache API responses for 5-60 seconds with s-maxage. This absorbs traffic spikes without serving significantly stale data. A 30-second cache on a popular API endpoint can reduce origin load by 90% during peak traffic.

Stale-While-Revalidate

Serve cached content immediately while checking for updates in the background. Users get instant responses, and the data is never more than one TTL cycle old. Ideal for dashboards and feeds.

Edge Computing

Run code at the CDN edge (Cloudflare Workers, Fastly Compute). Process requests, modify responses, or serve personalized content without hitting your origin. Sub-millisecond cold starts make this viable for real-time applications.

WebSocket Through CDN

Most CDNs now support WebSocket connections. Cloudflare passes WebSocket traffic through its network, providing DDoS protection and routing optimization for real-time applications like chat and live updates.

Performance Metrics: Cache Hit Ratio

The most important CDN metric is your cache hit ratio — the percentage of requests served from cache versus those that hit your origin. A well-configured CDN should achieve 90-99% cache hit ratio for static content.

95%+
Target Cache Hit Ratio
80-90%
Needs Optimization

If your cache hit ratio is below 80%, investigate these common causes:

  • Missing or incorrect Cache-Control headers on your origin
  • Query strings creating unique cache keys for the same content
  • Vary header set too broadly (e.g., Vary: *)
  • Content being marked as private or no-store unintentionally
  • Low traffic to specific URLs (cache expires before next request)
  • Cookies being sent for static asset requests

Common CDN Mistakes

MistakeImpactFix
Caching authenticated contentSecurity breachUse private, no-store for any response containing user data
Missing Vary headerWrong content servedAdd Vary: Accept-Encoding minimum; Vary: Accept for image format negotiation
Caching Set-Cookie responsesSession hijackingStrip Set-Cookie from cacheable responses or mark them no-store
Too-short TTL on static assetsLow hit ratioUse 1-year TTL with cache busting for versioned assets
No cache purge automationStale contentIntegrate CDN purge API into your deployment pipeline
Ignoring mobile vs desktopWrong version servedUse Vary: User-Agent or responsive design (no separate mobile site)

Cost Analysis

CDN pricing varies significantly by provider and usage pattern. Here is a realistic cost breakdown for a site serving 1 TB of content per month:

ProviderMonthly Cost (1 TB)Notes
Cloudflare Free$0Unlimited bandwidth on free plan; limited features
Cloudflare Pro$20/monthImage optimization, WAF, more analytics
BunnyCDN$10Pay-per-use, no minimum commitment
KeyCDN$40Pay-per-use, $4 minimum
AWS CloudFront$85First 10 TB at $0.085/GB
Fastly$100+Enterprise features, real-time logging
Panelica and Cloudflare Integration: Panelica includes deep Cloudflare integration: connect your Cloudflare account, manage DNS, purge cache, and configure SSL mode — all from the panel without logging into the Cloudflare dashboard. When you add a domain in Panelica, it can automatically configure Cloudflare DNS records, set the appropriate SSL mode, and enable recommended caching settings.

Implementation Checklist

Whether you choose Cloudflare, BunnyCDN, or any other provider, follow this checklist to ensure your CDN is configured correctly:

  • Set proper Cache-Control headers on your origin for every content type
  • Use "Full (Strict)" SSL mode — never Flexible
  • Add Vary: Accept-Encoding to all text-based responses
  • Enable compression (Gzip and/or Brotli) at both origin and CDN
  • Never cache responses containing Set-Cookie or authentication data
  • Use cache busting (filename hashing) for CSS and JavaScript
  • Set up automatic cache purging in your deployment pipeline
  • Monitor cache hit ratio — target 90%+ for static content
  • Enable HTTP/2 and HTTP/3 at the CDN edge
  • Configure Origin Shield if your server has limited capacity

A properly configured CDN is one of the most cost-effective performance investments you can make. The combination of reduced latency, decreased origin load, improved reliability, and built-in security makes CDN adoption a no-brainer for any serious website. Start with Cloudflare's free tier to experience the benefits immediately, then evaluate paid options as your traffic grows and your optimization needs become more specific.

Security-first hosting panel

Stop bolting tools onto a legacy panel.

Panelica is a modern, security-first hosting panel — isolated services, built-in Docker and AI-assisted management, with one-click migration from any panel.

Zero-downtime migration Fully isolated services Cancel anytime
Share:
No add-on tax.