Tutti i sistemi operativi · 40+ PoPHosting dal 2010
INTERKVM HOST SRL·AS 25198
Home/Blog/Building a CDN origin server: sizing and caching
Bandwidth 26 agosto 2026

Building a CDN origin server: sizing and caching

The edges take the load until a purge, a deploy or a cold region sends every one of them to the origin at once. Hit-ratio arithmetic, the cache headers that are the whole contract, and which machine to actually build.

Pubblicato
Lettura
5 min
Diagram of one origin server serving four CDN edges, with cache hit ratios shown per edge and the origin absorbing the misses.

A CDN origin server is the least glamorous machine in a delivery stack and the one that decides whether the whole thing holds up. The edges take the load, right up to the moment they do not: a cache purge, a new release, a cold region or an expiry storm, and suddenly every edge in the fleet is asking the origin for the same object at the same second. Sizing and configuring for that moment — not for the steady state — is the whole job.

What the origin actually serves

The useful number is the cache miss rate, not the viewer count.

origin egress = total delivered bytes × (1 − cache hit ratio)

At a 95% hit ratio, 40 Gbps of viewer traffic reaches the origin as roughly 2 Gbps. That is the reassuring version. The honest version has three corrections:

  • The miss rate is not evenly spread. It clusters around deploys, purges, expiries and cold regions. Your peak origin load can be many times its average.
  • Cold cache-fill is a burst. A new large object requested by twenty edges at once is twenty full-size transfers, in parallel, at whatever rate the edges can pull.
  • Long-tail catalogues never reach 95%. A media library where most titles are watched rarely will sit far lower, because the tail is always a miss.

Size the origin for the burst. An origin that serves 2 Gbps on a normal day and stalls at 12 Gbps during a release is an origin that fails exactly when it is being watched. The per-server capacity arithmetic — and what runs out before the port does — is in how many viewers can one streaming server serve.

Cache headers are the whole contract

Everything the CDN does is dictated by what the origin says. Get the headers right and the hit ratio follows.

Separate browser TTL from edge TTL. s-maxage applies to shared caches, max-age to the browser. Long at the edge, short in the browser, is usually what you want:

Cache-Control: public, max-age=300, s-maxage=86400

Use immutable content addressing where you can. A file whose name contains a content hash can never change, so it can be cached effectively forever:

Cache-Control: public, max-age=31536000, immutable

This is the single largest hit-ratio improvement available to most sites, and it removes revalidation traffic entirely.

Serve stale rather than serving nothing. stale-while-revalidate lets the edge return the cached copy immediately and refresh in the background; stale-if-error keeps you online while the origin is not:

Cache-Control: public, s-maxage=600, stale-while-revalidate=86400, stale-if-error=604800

Keep Vary minimal. Every value of a Vary header multiplies the number of cache entries for the same object. Vary: Accept-Encoding is normal and necessary. Vary: User-Agent fragments your cache into thousands of near-identical copies and is almost never what was intended.

Send validators. ETag and Last-Modified let a revalidation return a 304 instead of the object. On a large file that is the difference between a few hundred bytes and a few hundred megabytes.

The failure modes worth designing against

Thundering herd

Twenty edges miss on the same object simultaneously and issue twenty identical requests. Most CDNs offer request coalescing or an origin shield — a middle tier that absorbs the fan-in and makes one request upstream. Turn it on. It is the difference between one cache fill and twenty.

Range requests

Video players do not fetch files, they fetch byte ranges. The origin must honour Range and return 206 Partial Content, and the CDN must be configured to cache ranges rather than fetch the whole object per range request. An origin that ignores Range and returns 200 with the full body will move enormous amounts of data to satisfy small seeks.

Caching the wrong things

A 5xx cached with a long TTL turns a brief outage into a long one. Set short, explicit TTLs for error responses, and make sure your health checks and cache rules agree about what an error is.

Purge as a load event

A wildcard purge across a large catalogue schedules a cache-fill storm. Prefer content-addressed URLs, which never need purging, and where you must purge, do it narrowly.

Building the machine

The origin's shape depends on which resource the catalogue exhausts.

Storage-led — a large media library, most of it cold. Capacity is the constraint, so high-density drives with a flash tier for the hot working set. Our storage servers are the build for this, and the drive-class trade-offs are in NVMe, SATA SSD or HDD.

Throughput-led — a smaller catalogue, high concurrency, large objects. NVMe throughout, plenty of RAM for page cache, and a port sized for the fill burst rather than the average. A 10 Gbps configuration is the usual starting point; above that it is a question of how many edges pull at once.

Whichever it is, three things matter more than the CPU:

  • RAM. Page cache is your real first-level cache. An origin whose working set fits in RAM barely touches disk.
  • An unmetered port. Cache-fill traffic is bursty and irregular, which is the worst possible shape for 95th-percentile billing and a non-event on an unmetered line.
  • Something in front of the disks. A cache-fill burst is a random-read workload no matter how sequential each individual file is.

Add a reverse proxy in front of the application even when a CDN is already there — nginx or Varnish on the origin absorbs duplicate requests locally, holds a disk-backed cache, and gives you somewhere to fix header mistakes without a deploy.

Frequently asked questions

What cache hit ratio should I expect?

For a small catalogue of popular objects, 95% or better is achievable. For a long-tail media library, 70–85% is more realistic, and the tail will always miss. Measure yours before sizing anything — the number is specific to your catalogue and your audience.

Should the origin be in one location or several?

One origin is simpler and correct for most workloads, provided it has the capacity and the network to serve every edge. Add a second when the first cannot survive its own failure, or when a region is far enough away that fill latency hurts. Two origins introduce a consistency problem that did not previously exist.

Do I need TLS between the CDN and my origin?

Yes. The link crosses the public internet like any other, and terminating TLS at the edge while running plaintext to the origin means your content and headers traverse networks you do not control. The cost is a handshake per connection, which connection reuse amortises to nearly nothing.

Can I skip the CDN and serve from the origin directly?

If your audience is concentrated in one or two regions and your object sizes are large, yes — an unmetered port near your users can be cheaper and simpler than a CDN, and the arithmetic favours it more the higher your bitrate. It stops working as soon as your audience spreads out, because you cannot fix distance with capacity.

Next steps

Measure your hit ratio, then size the origin for the miss burst rather than the average. The video-on-demand page covers the storage-and-egress side of this, and dedicated tiers list the ports that can absorb a fill storm without slowing the edges down.

Tweaksv1
Theme