Video Streaming Platform
Ingest, transcode, package, authorize, and deliver on-demand video globally.
Product overview
Accept source videos, produce validated adaptive renditions, authorize playback, and deliver segments efficiently through a CDN.
Main actors
Viewer, Publisher, Moderator, Operations.
Assumptions
- Video on demand, not live streaming
- Object storage is the durable media store
- A CDN serves immutable segments
- Entitlement rules exist but billing is external
Non-goals
- Codec implementation
- Global rights negotiation
- Claiming a specific commercial platform architecture
- User-generated livestreaming
Requirements
Must-have
- Resumable direct upload
- Transcode pipeline
- Adaptive bitrate packaging
- Playback authorization
- CDN delivery and lifecycle
Should-have
- Captions
- Thumbnails
- Moderation review
- Resume position
Future scope
- Live video
- Offline licenses
- Personalization
- Multi-CDN steering
Non-functional decisions
| Concern | Decision |
|---|---|
| Durability | Source and published renditions use versioned object storage; metadata references immutable keys. |
| Availability | Published playback continues from CDN during control-plane degradation. |
| Latency | Startup depends on compact manifests and nearby first segments; ingest throughput is asynchronous. |
| Consistency | Asset publication is atomic at a version pointer; view analytics are eventual. |
| Security | Upload and playback grants are narrow, expiring, and never expose storage credentials. |
User roles
| Role | Access boundary |
|---|---|
| Viewer | Entitled published assets |
| Publisher | Own uploads, metadata, publication |
| Moderator | Review queue and policy outcome |
| Operations | Pipeline replay/quarantine, audited |
Core workflows
Domain model
| Entities | Relationship |
|---|---|
Video → VideoVersion | Metadata points to one published immutable version |
UploadSession → UploadPart | Tracks resumable source ingest |
VideoVersion → Rendition → Segment | Package describes bitrate-specific immutable objects |
VideoVersion → ProcessingJob | Stage/attempt workflow |
Viewer → PlaybackGrant | Short-lived entitlement decision |
Database design
PostgreSQL remains the transactional source of truth. Add specialized stores only for the workloads called out below.
video_versions — Immutable processing/publication unit
upload_sessions — Bounded direct upload grant
processing_jobs — Resumable pipeline stages
playback_progress — User resume projection
Transaction and retention boundaries
- Finalize verifies provider-reported parts/checksum then marks session complete and enqueues probe via outbox
- Publish switches current_version_id only after all required outputs and moderation pass
- Processing jobs use leases and unique stage/input hash
- Delete metadata first marks unavailable; media lifecycle deletion is delayed and recoverable
API design
| Endpoint | Purpose and permission | Idempotency / status |
|---|---|---|
POST /v1/uploads | Create bounded multipart upload Publisher | Required 201, 413, 429 |
POST /v1/uploads/:id/complete | Verify object and begin processing Session owner | Same parts/checksum returns result 202, 409, 422 |
GET /v1/videos/:id | Read published metadata Catalog visibility | Not required 200, 404 |
POST /v1/videos/:id/playback-grants | Authorize short-lived manifest access Entitled viewer | Not required; token is short-lived 201, 403, 451 |
PATCH /v1/videos/:id/publish | Switch published version Publisher/moderator policy | Version precondition 200, 409, 422 |
List endpoints use opaque keyset cursors unless a small bounded collection is explicit. Unknown objects return 404 where 403 would leak existence.
Architecture
System context
Main application architecture
Critical workflow sequence
Event model
| Event | Producer → consumers | Delivery |
|---|---|---|
UploadFinalized | Upload API → Probe worker | Outbox; unique stage/input hash |
RenditionCompleted | Transcoder → Packaging coordinator | At-least-once and checks output checksum |
VideoPublished | Catalog → CDN prewarm, search, notifications | Versioned and replayable |
Failure modes
Metadata without object
Failure
Upload finalize claims success but object is missing.
Mitigation
HEAD/checksum before transaction; do not trust client-reported completion.
Worker crash
Failure
Transcoder dies after writing some segments.
Mitigation
Write attempt-specific prefix, lease job, validate complete outputs, then promote by metadata pointer.
Duplicate job
Failure
Same stage executes twice.
Mitigation
Unique input hash and deterministic immutable outputs; only one state transition wins.
Poison media
Failure
Malformed source crashes codec tooling.
Mitigation
Sandbox workers, resource limits, file probing, quarantine and bounded retries.
Premature publish
Failure
Manifest references missing renditions.
Mitigation
Publication transaction checks required stage/QC records and immutable objects.
Token leak
Failure
Playback URL is shared.
Mitigation
Short TTL, scope to asset/region/device policy, optional cookie-based segment authorization.
Consistency and concurrency
Strong consistency / transactions
- Upload finalization
- processing stage state
- published-version pointer
- entitlement at grant issuance
Eventual convergence
- CDN fill/purge
- view counts
- search index
- resume position
Concurrency controls
- Unique stage/input constraint prevents duplicate logical jobs
- Lease with compare-and-set supports worker recovery
- Publish uses expected current version
- Progress uses monotonic client timestamp/version, not blind last arrival
Caching and background work
Safe to cache
- Immutable segments for long TTL
- Versioned manifests
- Published metadata
- Entitlement-independent catalog
Never a cache authority
- Raw source
- moderation-only content
- long-lived entitlement decision
Content-addressed/versioned media gets immutable caching. Playback grants are short-lived; revoke through key/version rotation for urgent cases.
Background jobs
- Probe
- Transcode fan-out
- Package manifests
- Generate thumbnails/captions
- Moderation/QC
- Orphan cleanup and storage lifecycle
Security boundaries
Security claims here are design controls, not certification. Threat modeling and jurisdiction-specific review remain required.
- Presigned uploads restrict object key, type, size, and expiry
- Untrusted media processed in network-isolated, resource-limited workers
- Playback grants enforce entitlement and territorial/device rules
- Private origins accept only CDN/service identity
- Validate filenames and never pass user strings to shell
- Audit publish/unpublish and moderation
- Protect telemetry endpoint from amplification and fabricated views
Observability
Logs
- Upload finalize verification with version, object metadata, and checksum result
- Processing stage lease, input hash, worker image, attempt, and output validation
- Publication/entitlement decision without playback token or source URL
Metrics
- Multipart completion and abandoned-upload rate
- Transcode queue age, encode duration, and failure rate by codec/rendition
- Publish lead time and missing-output validation failures
- Playback startup, rebuffer ratio, manifest errors, and CDN origin miss rate
Traces
- Trace upload finalization through probe, transcode fan-out, packaging, QC, and publish
- Sample playback-grant and origin-miss paths without tracing every media segment
Alerts
- Oldest required transcode stage breaches publish SLO
- CDN origin error/miss surge threatens playback
- Published manifest validation or entitlement service failure rises materially
Testing strategy
| Layer | What it proves |
|---|---|
| Unit | Pipeline state machine, entitlement rules, manifest builder |
| Integration | Multipart finalize, queue leases, object checks, publish gate |
| Contract | Object/CDN APIs and player manifest fixtures |
| Concurrency | Duplicate stage execution, stale leases, and simultaneous publish attempts |
| Failure | Worker death, corrupt input, missing segment, stale lease |
| End-to-end | Upload small fixtures → publish → authorized playback |
| Load | Ingest burst and playback cache-miss workload; report assumptions |
Do not mock PostgreSQL constraints, transaction isolation, object-store semantics, or provider contract fixtures in the tests intended to prove those boundaries.
Deployment evolution
Scale evolution
These are architecture scenarios, not throughput claims. Each transition should follow measured workload and reliability pressure.
| Scenario | Architecture may evolve toward | Decision rule |
|---|---|---|
| 1K users | One API, PostgreSQL for the catalog and processing jobs, object storage for sources and renditions, a transcode worker, a CDN | Make every processing stage idempotent and resumable; publish a title only after every required rendition exists |
| 100K users | Scale CPU/GPU worker pools by queue/stage; use CDN origin shield; isolate telemetry ingestion | Scale worker pools on transcode queue age; add an origin shield when CDN origin misses drive storage egress |
| 1M+ users | Regional ingest and processing close to storage; multi-CDN only after measured availability/performance need; immutable media avoids cross-region writes | Process near the ingest region's storage; add CDNs or regions only for measured playback-startup or availability gaps |