Video on demand is the friendliest workload a CDN ever gets: every file is immutable, popularity follows a predictable curve, and nothing has to happen in real time. Yet VOD estates routinely run with short TTLs, token-fragmented caches and duplicated packaging — paying live-streaming prices for library content. The right configuration mostly consists of getting out of the workload’s way.
Why VOD is the easy case — treated wrongly
A VOD title is a folder of files that will never change: init segments, media segments per bitrate rung, manifests. Unlike live, there is no freshness problem — the only questions are how many copies exist (packaging), who may fetch them (tokens), and how long edges keep them (TTLs). Most VOD misconfiguration comes from copying live settings — short manifest TTLs make sense for a stream that updates every four seconds and are pure waste for a manifest that will be identical in five years. Start from the premise that everything is cacheable forever and add restrictions only where the business requires them.
Package once: CMAF, ladders and storage layout
Package into CMAF so HLS and DASH reference the same media files: one set of segments on storage, one set of objects in cache, roughly half the footprint of maintaining TS and fMP4 side by side. Build the bitrate ladder for your actual audience — each rung multiplies storage and dilutes per-object cache efficiency, so a rung nobody’s bandwidth selects is a standing cost — and lay titles out under clean prefixes (/vod/<title>/<rendition>/) because every downstream control — token scopes, purge patterns, cache rules, analytics — keys off the path structure. Store on an origin whose economics fit large cold libraries; egress-free object storage pairs particularly well with VOD, since the long tail guarantees a steady trickle of origin fetches forever, and the pricing side of that decision is covered in video CDN pricing.
TTLs and versioning: immutable means immutable
Give segments and init files the longest TTL your platform offers — a year, with immutable in Cache-Control so well-behaved clients skip revalidation. Manifests can match, with one condition: nothing at an existing URL is ever edited. Re-encodes, fixed subtitles, replaced audio tracks all publish under a new version path (/v2/), and the application points players at the new manifest — the same discipline as asset versioning, applied to media. That rule makes purges an exceptional act (takedowns, legal removals) rather than an operational one; when you do purge, purge by the title’s prefix and confirm against the tail of the ladder, not just the manifest. The payoff for immutability is that hit ratio becomes a pure function of popularity and cache size, and your TTL decision tree for VOD collapses to a single branch.
Tokens without shredding the cache
Paid or private libraries need access control, and the standard mistake is per-URL tokens in the query string with the query string left in the cache key — identical segments cached once per viewer. For segmented media the clean pattern is a session-scoped grant: a signed cookie (or a signed path prefix) issued when playback is authorized, covering the whole title for the viewing window, validated at the edge and excluded from the cache key entirely. Scope grants to the title prefix from section two, set expiry to a generous viewing session rather than a paranoid few minutes (a token that expires mid-film is a support ticket, not security), and rotate signing keys with a dual-key window. The full mechanics — URL vs cookie, scopes, rotation, clock skew — are in signed URLs and cookies; the VOD-specific rule is simply: one grant per session, never one per segment, and the cache never sees the difference between viewers.
The long tail, the shield and the checklist
VOD popularity is head-heavy: a small fraction of titles produce most traffic and stay hot at the edge on their own, while the tail misses steadily. An origin shield converts those scattered edge misses into single origin fetches and is usually worth it for libraries beyond trivial size; pre-warming, by contrast, is only worth it for predictable premieres — push the first minutes of a launching title, not the library. The bring-up checklist: response headers show the year-long TTLs and immutable flag; the same segment requested through two sessions produces one cached object (token exclusion working); hit ratio per title follows popularity rather than sitting uniformly low (the fragmentation signature); and a test purge of one title’s prefix removes the whole ladder. After that, VOD delivery should be the quietest dashboard you own.
