CMD Guide
HomeSystem DesignSystem Design Problems

Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced

Why "just run ffmpeg" stops working

Most YouTube designs stop at "upload to blob storage, transcode, serve from CDN." The transcode box is where the engineering actually is, and it is the part most candidates wave through. This page opens that box.

Three facts force the design:

So one upload fans out into many encoding jobs, each expensive and slow, and different creators want different work done — some supply their own thumbnails, some want watermarks, some upload HD and some do not. A hardcoded pipeline cannot express that variability, and a pipeline that runs every stage for every upload wastes enormous compute. That tension is what the DAG solves.

Left panel shows a transcoding DAG: the original video splits into video, audio and metadata; the video branch fans out into encode 1080p, encode 720p, thumbnail and watermark tasks, while the audio branch leads to encode audio. Sibling tasks have no edge between them so they may run in parallel. Right panel shows the resource manager with a priority task queue, a worker queue ordered by utilization, a running queue of task-to-worker bindings, and a task scheduler that takes the highest-priority task, picks the least-loaded worker, runs it, binds it into the running queue, and removes the binding on completion.
Left panel shows a transcoding DAG: the original video splits into video, audio and metadata; the video branch fans out into encode 1080p, encode 720p, thumbnail and watermark tasks, while the audio branch leads to encode audio. Sibling tasks have no edge between them so they may run in parallel. Right panel shows the resource manager with a priority task queue, a worker queue ordered by utilization, a running queue of task-to-worker bindings, and a task scheduler that takes the highest-priority task, picks the least-loaded worker, runs it, binds it into the running queue, and removes the binding on completion.

The DAG model: make the pipeline data, not code

Facebook's streaming video engine expresses video processing as a directed acyclic graph, and this design adopts the same model. Tasks are declared as stages with dependency edges; the engine derives what may run sequentially and what may run in parallel. Two properties matter:

The first split is video, audio and metadata. The video branch then fans out into the work you actually care about: encodings at several resolutions/bitrates, thumbnail generation, watermarking. Typical tasks:

The six components, and what each one is really for

Preprocessor — four jobs

  1. Video splitting into GOP alignment. A Group of Pictures is a chunk of frames, usually a few seconds, that is independently playable. This is the single most important primitive on the page: because a GOP decodes without reference to its neighbours, GOPs can be encoded in parallel, uploaded in parallel, retried individually, and streamed adaptively. Split at the wrong boundary and none of that holds.
  2. Split on behalf of old clients. Some older devices and browsers cannot split video themselves, so the server does it for them.
  3. DAG generation from the creator's configuration files.
  4. Cache the segments. GOPs and metadata are persisted to temporary storage so that a failed encode can be retried from the segments rather than from the original upload.

DAG scheduler — graph to queued work

The DAG scheduler splits the graph into stages of tasks and puts them into the resource manager's task queue. In the traced example, stage 1 is the split into video/audio/metadata; stage 2 takes the video file into video-encoding and thumbnail tasks and the audio file into audio-encoding. The scheduler's only job is translating dependency structure into "these tasks are runnable now."

Resource manager — three queues and a scheduler

This is the component most often missing from a candidate's answer, and it is where efficiency comes from:

The loop: take the highest-priority task; take the best worker from the worker queue; instruct that worker to run it; bind task and worker into the running queue; remove the entry when the job completes. Note what the running queue buys you beyond bookkeeping — it is the crash-recovery record. A worker that dies mid-task leaves its binding behind, which is exactly the signal needed to re-dispatch that task rather than lose the upload silently.

Task workers, temporary storage, encoded video

Task workers execute the DAG's tasks, and different workers may specialize in different task types. Temporary storage is deliberately plural — choose per data shape: metadata is small and accessed constantly by workers, so cache it in memory; video and audio segments are large and streamed, so put them in blob storage. Data in temporary storage is freed once processing completes, which is what keeps the staging tier from growing without bound. The output is the encoded rendition, e.g. funny_720p.mp4.

Optimizations, and the trade each one makes

Speed

Safety

Cost

Video streams follow a long-tail distribution: a few videos are watched constantly, most are watched rarely or never. Four consequences follow:

  1. Serve only popular videos from CDN; serve the tail from your own high-capacity storage servers.
  2. For unpopular content, do not pre-generate every rendition — short videos can be encoded on demand. This trades first-view latency for storage and encode cost, which is the right trade for a video with three lifetime views and the wrong one for a video about to trend.
  3. Some videos are popular only regionally — do not distribute them globally.
  4. At sufficient scale, build your own CDN and partner with ISPs, as Netflix does. A giant project, justified only when egress dominates your entire cost structure.

All four depend on knowing your access patterns, so analyze historical viewing before optimizing. Pre-generating every rendition for every upload is the default that quietly costs the most.

Which pipeline shape, when

ApproachBest forWhy it winsWhen it is wrong
Hardcoded pipelineOne uniform output profileSimplest possible thing; no scheduler, no configThe moment two creators need different processing, or you must skip stages to save cost
DAG + resource managerHeterogeneous, high-volume processingPer-upload graphs, derived parallelism, per-task retrySmall scale — you have built a scheduler to run three tasks
Pre-encode all renditionsContent you know will be watchedInstant playback at any qualityLong-tail libraries — you pay encode + storage for views that never happen
Encode on demandRare, short videosZero cost for never-watched contentPopular or long videos — first viewer eats the encode latency
Serve everything from CDNUniformly hot catalogsLowest latency everywhereLong-tail catalogs — egress on cold content dominates the bill

Error handling — the distinction that drives the retry policy

The specific playbook: upload errors retry a few times; a client that cannot split by GOP falls back to server-side splitting; transcoding errors follow the recoverable/non-recoverable split above.

Pitfalls

Cost model — what dominates the bill

Transcoding has an unusual cost shape: it is CPU-dominated at ingest and egress-dominated at playback, with storage a distant third.

Rough BOTE. Take 5 million daily active users, 5 videos watched each, 10% of users uploading one video a day at ~300 MB average: that is ~500,000 uploads/day → ~150 TB/day of originals. Encoding into, say, five renditions typically costs on the order of the video's own duration in CPU-minutes per rendition, so an hour of video becomes several CPU-hours — hundreds of thousands of CPU-hours per day. At roughly $0.03/vCPU-hour, the encode fleet alone runs to tens of thousands of dollars per day. Playback then pays CDN egress at roughly $0.02/GB, and because every watched byte leaves the CDN, egress scales with views rather than uploads.

Dominant line items: CDN egress on the popular head of the catalog, and encode CPU for renditions — especially renditions of tail content nobody watches.

Levers, in order of leverage: (1) serve the tail from origin storage rather than CDN, cutting the most expensive line for the least-watched content; (2) encode the tail on demand, deleting the encode cost for videos with no viewers; (3) drop the highest-bitrate rendition for content whose audience never selects it; (4) region-scope distribution. Each of these is a popularity bet, which is why the historical-access analysis is not optional — guessing wrong on the head is far more expensive than guessing wrong on the tail.

Operability: the fingerprints of a broken transcode pipeline

Each failure leaves its own trace. A rising count of videos stuck in "processing" with an idle worker fleet means bindings are orphaned in the running queue — workers died and nothing reconciles, so the tasks were never re-dispatched. Encode retries clustered on one segment index across many unrelated videos points at GOP splitting, not at the videos: the splitter is producing one malformed chunk shape. Task-queue depth growing while worker utilization sits below capacity means the scheduler cannot place work — usually a specialized task type with no eligible workers, which looks like a capacity problem and is actually a placement problem. Tail-latency spikes on first playback of older videos is the on-demand encoding path being hit, i.e. your popularity classifier put something in the tail that viewers actually want.

The most expensive silent failure is temporary storage that never drains: if the cleanup that frees GOPs on completion fails, the staging tier grows monotonically and the bill climbs with no user-visible symptom until you run out of space mid-encode. The subtler one is low-priority starvation — measure the age of the oldest queued task, not just queue depth, because depth can look healthy while the bottom of the queue is days old. Signals worth having: oldest-binding age in the running queue, per-segment retry counts, task-queue age histogram by priority, staging-storage bytes versus in-flight video count, and on-demand-encode hit rate.


Re-authored for this guide from the Alex Xu Vol. 1 YouTube chapter (DAG model after Facebook's streaming video engine); DAG + resource-manager diagram hand-authored as SVG. Deep dive complementing the existing "Designing YouTube or Netflix" and "Designing YouTube/Netflix — Transcode, CDN & Adaptive Bitrate, Traced" pages — those cover streaming, ABR and CDN strategy; this one covers the processing pipeline itself.

🤖 Don't fully get this? Learn it with Claude

Stuck on Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced** (System Design) and want to truly understand it. Explain Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Video Transcoding at Scale — DAG Pipeline, Scheduler & Resource Manager, Traced** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes