Storage Schema and Detailed Components
In one line: the data model is small, the delivery machinery is not — which is the normal shape of a media system.
The storage schema
Five entities, and the fifth is the one most write-ups leave out.
The video is not in the database
There is a manifest_uri, not a video. The bytes live in blob storage; the database holds a pointer.
That is the claim-check pattern, and it is essential here. A relational database holding multi-hundred-megabyte blobs collapses on backups, replication, and query performance all at once. Keeping the row small and pointing at object storage lets metadata queries stay fast and lets the two systems scale on their own terms.
Why RENDITION exists
Most simplified schemas give VIDEO a single video_URI column and move on. That is wrong in a way worth being explicit about, because an interviewer will push on it.
One video is many files — one per resolution, per codec. Add per-shot encoding and it becomes segments × qualities × codecs, which is hundreds of objects for a ten-minute video. A single URI column cannot express that.
So RENDITION is a one-to-many child of VIDEO, and manifest_uri on the parent points at the index that ties them together. Volunteering this is a cheap signal: it shows you know the simplified diagram is simplified.
The components
| Component | Role |
|---|---|
| Load balancers | Distribute requests across web servers |
| Web servers | Handle requests and interface with API servers |
| Upload service | Auth, quota, dedupe check, presigned URL issue, per-part tracking |
| User store | Strongly consistent, bounded by user count, rarely written |
| Video metadata store | Eventually consistent, grows forever, written on every view and like |
| Thumbnail store | Bigtable-style key-value for references; the images themselves in object storage |
| Raw upload store | Holds originals; cold after processing, kept for re-transcoding to future codecs |
| Segment store | Renditions and manifests — the objects actually served |
| Transcoding fleet | Runs the processing DAG; splits, encodes, generates thumbnails, writes manifests |
| CDN and colocation | Cache popular content near users; colocation where a dedicated site is not feasible |
Split storage by consistency, not by size
The two datasets have opposite requirements on every axis. Keeping them in one system forces the stricter requirement onto both — strong consistency on a dataset that does not need it, at enormous volume.
Splitting them lets each be tuned independently, and it is what makes "eventual consistency for content, strong consistency for user data" implementable at all rather than just stated.
The transferable rule: split storage by consistency requirement, not just by size.
Why thumbnails get their own system
Thumbnails look trivial and are not. Each video needs several, so the object count is a multiple of the video count — billions of small files, read on nearly every page load, since a search results page renders dozens at once.
That is the opposite profile from video. Videos are few-and-huge; thumbnails are many-and-tiny. A key-value store built for high-throughput access at scale fits the second; a blob store built for large sequential objects fits the first.
The split is careful, though: the store holds thumbnail references, and the images themselves sit in object storage. So even thumbnails are pointer-plus-blob. Structured metadata in a database, bytes in object storage, regardless of object size.
Caching, in three layers
Web servers cache pages; application servers cache objects; the CDN caches bytes.
That distinction is real. Object caching avoids refetching a piece of data — a video's metadata, a user's subscriptions — and is reusable across many different pages. Page caching avoids re-rendering an entire response and is reusable only for identical requests. Page caching is cheaper per hit and less reusable; object caching is more work per request and composes across pages.
Having both means a personalized page that cannot be cached as a whole still benefits from cached objects inside it. Add the CDN and there are three cache layers before origin, which is how a system serving 12 Tbps keeps origin load survivable.
Key takeaway
Five entities holding pointers, not bytes, with RENDITION as the one-to-many that a single video_URI column cannot express, and likes_count as a logical view over a sharded counter. Storage splits user data from video metadata by consistency requirement, not by size, because keeping them together forces the stricter guarantee onto the larger dataset. Thumbnails get their own store because they are many-and-tiny where videos are few-and-huge. Three cache layers — page, object, edge — sit between users and origin.
Interview signal by level
| Level | What a strong answer sounds like |
|---|---|
| L4 | "Tables for videos, users, channels, and comments, with the video files in blob storage." |
| L5 | Adds the renditions relationship and the storage split: "one video is many files, so renditions are a child table and the parent points at a manifest. User data and video metadata go in separate clusters so they can scale independently." |
| Staff+ | Splits by consistency and flags the counters: "the split isn't about size, it's about consistency requirement — user data needs strong consistency and video metadata doesn't, and keeping them together forces the stricter guarantee on the larger dataset. And likes_count as an INT column is a logical view: physically that's a sharded counter, because a viral video is a textbook heavy hitter with millions of concurrent increments to one row." |
Next: how search works.