Case studies
Transcoding as a DAG
Turn one uploaded master file into many renditions by splitting it into chunks and encoding each chunk in parallel, as a directed acyclic graph of small, retryable tasks.
Encoding a two-hour 4K master on one machine is slow, and a single failure wastes the whole run. So the encode is split into a graph of small tasks. Each task handles one chunk at one quality. Thousands of tasks can run at once, and a failed task retries alone.
Concept
Before you start
- DAG (directed acyclic graph): a set of tasks with arrows that show which must finish first. It has no loops, so there is always an order that works.
- Chunk: a slice of the video that can be encoded without the rest. Chunks are cut on keyframe boundaries.
The big idea
Picture a bakery making one batter in several cake sizes. The batter is poured into pans, each pan is baked at each size in parallel, and the finished cakes are boxed once all are done.
The picture breaks where the dependencies are real. Packaging must wait for every chunk, so the graph is parallel only where tasks are independent.
Walking through it
The pipeline has four stages:
inspect source → split into keyframe-aligned chunks
→ encode each chunk × each rendition, in parallel
→ package segments and write manifests
→ mark status = ready (thumbnails and checks run alongside)A concrete example: a 10-minute video split into 4-second chunks gives 600 ÷ 4 = 150 chunks. With five renditions, that is 150 × 5 = 750 encode tasks.
Each task is keyed by (video_id, chunk, rendition). If a worker is preempted on chunk 42 at 720p, only that one task runs again. The other 749 are untouched. That only works if the task is idempotent, meaning that running it twice gives the same output.
Codecs are a separate choice. H.264 is the most compatible. Newer codecs such as VP9, HEVC and AV1 compress better but need more encoding work and have uneven device support. Many platforms keep an H.264 ladder for compatibility and add a newer codec for capable devices. Each extra codec adds storage.
Common mistakes
- Splitting on arbitrary byte offsets. A chunk that does not start on a keyframe cannot be decoded on its own.
- Non-idempotent tasks. A retry then writes duplicate output, or a half-written file.
- Marking the title ready too early. Every rendition and sidecar the player may request must exist first.
- Adding codecs without counting storage. Every codec is another full set of files.
Check yourself
1. A worker dies while encoding chunk 42 at 720p. What runs again?
Answer: Only that task. Tasks are keyed by video, chunk and rendition, and running them again is safe.
2. Why does a 10-minute video with 4-second chunks produce 750 tasks?
Answer: 600 ÷ 4 = 150 chunks, and 150 chunks × 5 renditions = 750 tasks.
Key takeaways
- Split the master into keyframe-aligned chunks and encode each chunk for each rendition.
- Independent tasks run in parallel and retry on their own.
- Make tasks idempotent, so a retry never duplicates output.
- Mark the title ready only after every needed file exists.
Further learning
Next, see how the player chooses among these renditions in adaptive bitrate streaming.
Related
Case study: video streaming
YouTube and Netflix-style delivery, with resumable uploads, parallel transcoding into a bitrate ladder, HLS and DASH adaptive streaming, and CDN economics.
Message queues
A durable buffer between the code that creates work and the code that does it. Start here for the map of queue concepts.
Video segments and manifests
A video is stored as many short, immutable segments, listed in a manifest. The player downloads the small manifest first, then fetches segments in order from the nearest cache.