Guides

What is a CDN? How content delivery networks work, from the origin server's side

A CDN caches your site's files on servers near your visitors: how caching, cache headers and origin pulls work, what a CDN does not do, and origin setup.

Published ~9 min read

Short answer: a CDN, or content delivery network, is a network of servers spread across many cities that keeps copies of a website’s files close to its visitors. When someone opens the site, images, scripts, styles and videos come from the nearest CDN location instead of from the website’s own server, often on another continent. Pages load faster, the origin server does a fraction of the work, and traffic spikes and many attacks hit the CDN’s capacity instead of yours. Cloudflare, Akamai, Fastly, Amazon CloudFront and Bunny are well-known CDNs.

How does a CDN work?

Most CDNs work as a distributed reverse proxy. Your domain’s DNS points at the CDN, not at your server, and the CDN steers each visitor to a nearby location — a point of presence (PoP) — using DNS-based steering or anycast, where many PoPs announce the same IP address and the internet’s routing picks the closest.

  • Cache hit: the PoP already has a fresh copy of the requested file and answers at once. Your server never hears about the request.
  • Cache miss: the PoP fetches the file from your server — the origin — passes it to the visitor and keeps a copy for the next one, for as long as the cache rules allow.
  • Revalidation: when a stored copy expires, the PoP asks the origin whether it changed (If-None-Match with the file’s ETag). A 304 Not Modified answer costs a round trip but no transfer.

Larger CDNs add tiered caching or an origin shield: a miss at a small PoP asks a bigger regional PoP first, so the origin sees one request per file and region instead of one per city.

Why does a CDN make sites faster?

Distance. Every round trip between browser and server costs time set by physics, and a page load takes several: DNS, TCP, TLS, then the requests themselves. A CDN shortens each of those trips for cached content, and it terminates TLS at the edge, so even requests that must go to the origin save the handshake round trips over the long path. The difference between capacity and delay is explained in bandwidth vs latency; a CDN works on the latency side.

What does a CDN cache?

By default, mostly static files. Cloudflare, for instance, caches files by extension — images, CSS, JavaScript, fonts, archives, media — and does not cache HTML or JSON unless you add a rule. Whether and how long anything is stored is decided by the headers your origin sends:

Header valueMeaning
public, max-age=31536000, immutableCache for a year; the file never changes at this URL (use with versioned file names)
public, max-age=300, s-maxage=3600Browsers keep it 5 minutes, shared caches such as a CDN an hour
no-cacheMay be stored, but must be revalidated with the origin before each use
no-storeMust not be stored anywhere
privateOnly the visitor's browser may store it — never a CDN
stale-while-revalidate=60Serve the old copy for up to 60 s while fetching a new one in the background
nginx · long caching for versioned static files
location ~* \.(css|js|woff2|png|jpg|webp|svg)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    access_log off;
}

How do you tell whether a file came from the cache?

Check cache headers
curl -sI https://example.com/assets/app.css | grep -iE 'cache-control|age|cf-cache-status|x-cache'
  • cf-cache-status: HIT (Cloudflare) or x-cache: HIT (CloudFront, Fastly and others) — served from the edge.
  • MISS or EXPIRED — fetched from the origin this time; the next request should hit.
  • DYNAMIC or BYPASS — not eligible for caching by the current rules or headers.
  • Age — how many seconds the copy has been in the cache.

Without a terminal, the HTTP header checker lists the same headers for any URL. Run it twice on a static file: a cacheable one shows a hit the second time.

Request the same URL twice. A file that stays at MISS is being refused by the cache — usually a Set-Cookie, a private or no-store header, or a query string that changes every time.

What else does a CDN do?

  • Offloads bandwidth — the bulk of bytes comes from the CDN, so the origin’s port and traffic allowance go further.
  • Absorbs spikes — a viral link hits cached files, not your PHP workers.
  • Mitigates attacks — a proxy CDN sits in front of the origin and filters floods and abusive HTTP traffic with its own capacity, which is why it is the usual answer to application-layer DDoS attacks on public websites.
  • Modern protocols for free — HTTP/2, HTTP/3, Brotli and current TLS at the edge, whatever the origin runs.
  • Serves IPv6 at the edge even when the origin has only IPv4.

What a CDN does not do

  • It does not speed up uncached, dynamic requests much — a slow database query is just as slow behind a CDN.
  • It does not replace a working origin: when the origin is down, most CDNs show their own error page.
  • It does not hide the origin by itself. If the server’s IP address is known from old DNS records, a subdomain that is not proxied or mail headers, attackers go around the CDN straight to it.

How do you set up an origin server behind a CDN?

  • Firewall the origin to the CDN. Allow ports 80 and 443 only from the CDN’s published IP ranges (Cloudflare lists them at cloudflare.com/ips), and keep SSH limited to your own addresses.
  • Encrypt to the origin too. Use a real certificate on the origin and the CDN’s strict TLS mode. A “flexible” mode that talks plain HTTP to the origin, combined with an HTTPS redirect on the origin, is the classic redirect loop.
  • Restore visitor IPs. The origin sees CDN addresses; read the real client from the CDN’s header (CF-Connecting-IP at Cloudflare) via nginx’s real_ip_header, trusting it only from the CDN’s ranges.
  • Know the error codes. When the CDN cannot reach or understand the origin, it says so with its own status: at Cloudflare, 521 means the origin refused the connection, 522 that it timed out, 520 that it sent something unexpected and 524 that it took too long to answer.
nginx · real visitor IPs behind Cloudflare (repeat set_real_ip_from per range)
set_real_ip_from 173.245.48.0/20;   # one line per published Cloudflare range, IPv4 and IPv6
real_ip_header   CF-Connecting-IP;

Do you need a CDN?

  • Yes if visitors come from several continents, pages carry many images or scripts, you serve downloads or video, or the site is a target.
  • Probably not for an API used by a few servers in the same region, a private dashboard, or a site whose visitors are all near the server.
  • Not for everything: SSH, game servers, mail and databases do not go through a web CDN. Game traffic needs network-level protection at the host instead.

Running an origin server at VMHeaven

A VMHeaven VPS works well as a CDN origin: root access for the nginx settings above, its own IPv4 address to firewall, always-on DDoS mitigation at the network level, and servers in Amsterdam and Frankfurt, close to the CDN’s large European PoPs. Standard KVM suits most websites; if the origin mostly delivers large files, check the plan’s port speed, since cache misses and purges still come from your server. How to measure what a server’s network delivers is covered in testing VPS network speed.

Frequently asked

Does a CDN make every website faster?

It speeds up cacheable content — images, scripts, styles, downloads — for visitors far from the server, and shortens TLS setup. Uncached dynamic pages still wait for the origin, so a slow application stays slow.

Does a CDN hide my server's IP address?

A proxy CDN replaces it in DNS, but the address can still leak through old DNS records, unproxied subdomains or mail headers. Firewall the origin so only the CDN's IP ranges can reach the web ports.

What is the difference between a CDN and web hosting?

Web hosting runs your site — the origin server with its files, application and database. A CDN sits in front of it and delivers cached copies from many locations; it needs an origin to fetch from.

Related articles

All guides