Key takeaways
- Separate ingest, processing, storage, delivery, and playback before selecting products, then apply authorization across the complete request path.
- Build rendition ladders from source quality and measured audience conditions rather than a fixed list of resolutions.
- Package aligned renditions as HLS, MPEG-DASH, or CMAF and preserve every relative manifest and segment path during export.
A video CDN is not one box. Reliable on-demand playback comes from a chain whose ingest, processing, storage, delivery, and playback layers each have an explicit responsibility, with authorization applied as a cross-cutting policy. The design fails when a cached manifest points at replaced or not-yet-published segments, rendition paths break during export, or a live-streaming requirement is mistaken for file-based VOD processing.
What matters most
- Use versioned asset paths, deliberate cache policies, and one authorization model for manifests, segments, captions, and posters.
- Measure startup delay, rebuffering, playback errors, cache hit ratio, origin traffic, processing failures, and cost per published asset.
Assign each layer one clear responsibility
Start with the viewer and trace backward. The player interprets the manifest, selects a rendition, renders captions, reports playback events, and applies product controls. The CDN terminates viewer requests, enforces the selected delivery policy, caches responses, and fetches misses from an origin. Durable object storage owns approved manifests, segments, captions, posters, and any archive master. A processing service creates those outputs from a completed source. Upload or live-ingest infrastructure gets the source into that processing boundary. Authorization is a cross-cutting policy applied consistently to the delivery and playback request path, not a sixth media-processing layer.
The word “video CDN” often hides this decomposition. A CDN does not repair corrupt timestamps or author an adaptive ladder, and a transcoder does not automatically provide audience authorization, global caching, a player, or quality-of-experience analytics. Keep stable application-owned asset and version identifiers across the layers so a processing job, exported package, delivery request, and player error can be correlated without treating a filename as the database.
Ingest layer
Receives a complete upload or import, or finalizes a live recording before handing a durable source to processing.
Processing layer
Creates technically valid renditions and packages from the durable source handed over by ingest.
Storage layer
Owns approved files and exposes a controlled origin path; it is not the application’s asset catalog.
Delivery layer
Protects and caches viewer requests, fetches misses from the origin, and applies the chosen delivery policy.
Playback layer
Interprets the manifest, selects renditions, renders captions, and owns the viewing experience.
Create a ladder that earns its cost
Inspect the source before choosing outputs. Resolution, frame rate, codec, bit depth, audio layout, duration, and visual complexity constrain what can be useful. A 720p source cannot gain genuine detail from a 1080p encode. A low-motion lecture and a fast sports recording can need different bitrates at the same dimensions. Keep a high-quality archive source when future reprocessing matters, but do not send that master through the public playback path.
Encode a small set of renditions whose bitrate and dimensions provide meaningful switching steps. Use the same segment duration, aligned keyframes, and compatible timelines across the set. Validate visual quality on representative content rather than relying on resolution names. More renditions increase encoding minutes, stored bytes, package objects, validation time, and possible cache misses, so add one only when player telemetry shows a coverage gap.
Respect the source ceiling
Never invent captured detail by upscaling a source merely to fill a conventional ladder.
Use a representative corpus
Compare motion, gradients, text, faces, dark scenes, and audio synchronization at target bitrates.
Close the measurement loop
Tune the ladder from startup, rebuffering, and delivered-bitrate data rather than intuition alone.
Package adaptive outputs as one connected tree
HLS and MPEG-DASH packages are graphs of references rather than unrelated files. A top-level manifest identifies renditions, media playlists or representations identify media, and the media entries resolve segments. Captions, alternate audio, encryption metadata, and initialization segments can add more relationships. Validate the whole package from its public URL after export; checking only that the master manifest returns 200 misses broken descendants, MIME types, CORS rules, and authorization failures.
The sample creates two HLS-ready renditions in separate /video/encode Steps, then bundles them through /video/adaptive. The adaptive Step defines one segment_duration for the package; confirm that rendition timelines and keyframe settings remain compatible, especially before combining files prepared outside one controlled workflow. /s3/store then exports the resulting files. The adaptive results carry relative_path metadata. The destination combines the package-wide ${assembly.id} with ${file.meta.relative_path} and ${file.name}, so every result stays below one prefix and preserves the directory structure referenced by the playlists. Use a saved Template and least-privilege Template Credentials in production. Replace the example ladder, my_s3_credentials name, bucket and region configured in those Template Credentials, and vod path prefix with values tested for the source corpus, target players, and bucket. The sample sets acl to private deliberately because /s3/store otherwise defaults to public-read; configure the CDN’s private-origin access separately.
{
"steps": {
":original": { "robot": "/upload/handle" },
"hls_480p": {
"use": ":original",
"robot": "/video/encode",
"result": false,
"ffmpeg_stack": "v6",
"preset": "hls/480p"
},
"hls_720p": {
"use": ":original",
"robot": "/video/encode",
"result": false,
"ffmpeg_stack": "v6",
"preset": "hls/720p"
},
"vod_package": {
"use": {
"steps": ["hls_480p", "hls_720p"],
"bundle_steps": true
},
"robot": "/video/adaptive",
"result": true,
"technique": "hls",
"playlist_name": "master.m3u8"
},
"exported": {
"use": "vod_package",
"robot": "/s3/store",
"credentials": "my_s3_credentials",
"acl": "private",
"path": "vod/${assembly.id}/${file.meta.relative_path}/${file.name}"
}
}
}Make storage and cache behavior deployment-safe
Publish each approved package below an immutable version path, such as an asset ID plus a version or content digest. Upload every object, validate the package, and only then change the application record to expose the new master manifest. This makes publication atomic from the viewer’s perspective and avoids a new manifest pointing at segments that have not reached the origin. Retain or delete old versions according to an explicit rollback and retention policy.
Segments under immutable paths can normally receive long cache lifetimes because their bytes never change. A manifest that changes in place needs a shorter or actively invalidated policy, but versioning the complete VOD package is easier to reason about. Configure correct content types, byte-range behavior where required, CORS for the actual player origins, and consistent compression rules. Do not apply generic HTML caching assumptions to manifests and segments without testing the chosen player and CDN.
Publish atomically
A package becomes visible only after all referenced objects have been exported and validated.
Use immutable versions
The same URL always returns the same bytes, so cached media cannot silently mix releases.
Protect playback without destroying the cache
Choose whether a video is public, time-limited, or bound to an application entitlement. Apply the resulting policy to the master manifest, child manifests, segments, captions, posters, and downloads. Protecting only the first request is insufficient when a viewer can reuse the segment URLs directly. Keep private storage credentials and Transloadit signing secrets on trusted servers.
Every varying query parameter, cookie, or request header can affect cache reuse if it enters the cache key. Conversely, removing a security-relevant value from the key can cause one authorized response to be served in the wrong context. Prefer a small, documented set of delivery inputs, normalize them at the edge where appropriate, and test expiry, revocation, seeking, and concurrent segment requests. Keep secrets and personal data out of manifest and segment URLs because those URLs can appear in logs, analytics, browser history, and support traces.
Observe the complete path and rehearse failures
Processing telemetry should expose accepted input, each rendition, package creation, export completion, duration, and structured failure. Storage and CDN telemetry should expose missing objects, origin response time, cache hit ratio, bytes transferred, and response status by object class. Player telemetry should expose startup delay, rebuffering, fatal errors, selected bitrate, seek failures, and caption failures. Join those observations through stable asset and version identifiers while keeping viewer data appropriately minimized.
Test corrupt and unsupported sources, interrupted uploads, an unavailable export destination, partial packages, duplicate completion notifications, a stale manifest, an origin outage, expired delivery authorization, missing CORS headers, and an unsupported codec. Reconcile nonterminal processing jobs against authoritative status so a missed notification does not leave an asset stuck forever. Keep “processed,” “exported,” “playable,” “reviewed,” and “published” as separate states.
Design for repetition
Retry-safe paths and idempotent handlers prevent duplicate notifications from producing duplicate releases.
Reconcile missing events
A scheduled status check repairs state when a notification is delayed or never reaches the application.
Model cost per published and watched asset
Count source upload or import, every encoded output, packaging, captions, thumbnails, export, retained originals, stored segments, CDN requests, origin requests, and egress. Then add failures, retries, edits, and newly required formats. A larger ladder costs more before any viewer arrives, while a tiny-segment design can increase request volume and manifest overhead. Cache fragmentation moves work and traffic back to the origin.
Compare architectures with representative sources and audience distributions. Cost per input minute is useful for processing, but cost per published asset reveals failed and abandoned work, and cost per watched hour captures delivery behavior. Include engineering time for player compatibility, cache rules, authorization, observability, incident response, and migration. The cheapest advertised unit is not necessarily the least expensive reliable system.
Technical details worth knowing
- HLS and MPEG-DASH describe adaptive delivery packages; neither protocol by itself provides live ingest, storage, a CDN, a player, analytics, or entitlement checks.
- Adaptive switching depends on renditions having compatible timelines and aligned segment boundaries. Independently encoded files are not automatically safe to combine into one ladder.
- A master manifest references media playlists or representations, which in turn reference segments. Moving files without preserving those relative paths breaks playback even when every object exists.
- Manifests and media segments have different change patterns. Versioned VOD segments can use long-lived immutable caching, while mutable manifests need policy that matches publication and replacement behavior.
- CDN cache keys and authorization must be designed together. Query strings, cookies, or headers that vary unnecessarily can fragment the cache, while omitted authorization inputs can expose protected media.
- Segment duration, and therefore approximate segment size at a given bitrate, affects startup latency and how quickly a player can switch renditions.
- Byte-range addressing lets multiple segments live in one fMP4 or CMAF resource that players fetch with HTTP range requests, reducing object and cache-key count. It does not reduce total bytes delivered during linear playback and complements rather than replaces segmented delivery.
- Transloadit /video/adaptive packages prepared renditions as HLS, MPEG-DASH, or CMAF. Storage exports must retain each result’s relative_path metadata so the package remains connected.
- The application should not mark a video publishable merely because encoding finished. It must also verify export completeness, manifest validity, delivery access, captions, posters, and playback on target clients.
A practical approach
- 1
Draw the request and data path from source ingest through the viewer, assigning an owner to every transition.
- 2
Encode a small ladder from representative sources and validate switching on target devices and realistic networks.
- 3
Export the complete adaptive package to versioned storage paths and test it through the production CDN rules.
- 4
Run failure drills for partial exports, stale manifests, unavailable origins, expired authorization, and missing completion events.
When Transloadit is useful
Use a saved Template to turn uploaded, imported, or finalized recordings into a rendition ladder sized to measured conditions with /video/encode, package those renditions with /video/adaptive, and export the complete directory tree to owned storage. Put a CDN and player around the resulting VOD assets according to your delivery requirements.
Architecture boundary
Transloadit processes completed video files and can package adaptive video-on-demand (VOD) outputs, but it does not operate live ingest, a general-purpose CDN, or a video player. Live broadcasting and audience playback need dedicated components.
Frequently asked questions
Should every service publish both HLS and MPEG-DASH?
Not necessarily. HLS has broad native support in Apple environments, while MPEG-DASH is common in other player stacks. Some products publish both from common CMAF media, but that adds validation and operational work. Choose from actual device and player requirements, then test the exact manifests, codecs, captions, and authorization path.
Is there a standard adaptive bitrate ladder?
No. A useful ladder follows the source resolution, frame rate, visual complexity, target displays, and measured viewer bandwidth. Do not upscale beyond the source or add neighboring renditions that do not improve switching. Begin with a small ladder and adjust it using playback data.
How should I replace an already cached video?
Use a versioned, immutable path for each approved package and change the application’s asset pointer when a replacement is ready. This prevents a new manifest from referencing old or partially replaced segments and lets long-lived segment caching remain safe.
Can Transloadit power the live part of a video CDN?
It can prepare file-based video-on-demand assets after a complete file is uploaded, imported, or finalized by a live provider. It does not accept a continuous live input stream, sometimes called the contribution feed, or operate the live broadcast, so a live workflow needs a specialized ingest and distribution service.
What should I monitor first?
Track viewer startup time, rebuffer ratio, fatal playback errors, average delivered bitrate, CDN cache hit ratio, origin bytes, manifest and segment response failures, processing duration, export completeness, and cost per published asset. Keep player, CDN, storage, and processing identifiers joinable without putting private data in URLs.