Forge64 logo
All app types

Video streaming app architecture

Video streaming app architecture: the decisions that matter

The architecture of a video streaming app comes down to 4 choices: adaptive bitrate streaming with a transcoding ladder, object storage plus CDN, never the app server, for video bytes, batched watch events with rollups instead of per-second writes and entitlement checked at manifest issue. Each is explained below with the alternatives that were rejected and what you accept by choosing it.

Last checked

Adaptive bitrate streaming with a transcoding ladder

Situation: Viewers span phones on weak networks to 4K TVs; one fixed MP4 either buffers or wastes bandwidth.

Choice: Transcode every upload into a ladder of renditions packaged as segmented CMAF (HLS + DASH) so the player switches quality per segment.

  • Rejected: Serve the original MP4 (progressive download): simple but unusable on poor networks and wastes egress.
  • Rejected: Third-party video API only: fast to start but per-minute pricing scales poorly and removes control.
  • Consequence: Storage grows ~2-3x the source per title.
  • Consequence: Needs an async transcode queue and worker capacity limits.
  • Consequence: Playback quality is measurable per segment.

Object storage plus CDN, never the app server, for video bytes

Situation: Video egress is the dominant cost and the main scaling risk; app servers cannot hold long streaming connections economically.

Choice: Segments live in S3-compatible storage with immutable names and long cache lifetimes behind the edge cache; the app only issues short-lived manifests.

  • Rejected: Stream through Next.js routes: simple but caps scale and multiplies cost.
  • Rejected: Per-segment signed URLs: strong control but defeats caching.
  • Consequence: Origin load ~ cache misses only.
  • Consequence: Revocation is limited to manifest TTL, accepted for non-DRM content.
  • Consequence: Egress is metered and capped per plan.

Batched watch events with rollups instead of per-second writes

Situation: Watch history and resume position are write-heavy; a row per heartbeat per viewer would melt the primary.

Choice: Clients batch heartbeats; the server appends to a monthly-partitioned insert-only table and a cron rollup upserts one progress row per user and video.

  • Rejected: Update the progress row on every heartbeat: hot rows and lock contention.
  • Rejected: Skip server-side history: loses resume and recommendations.
  • Consequence: Resume position can lag by up to a minute.
  • Consequence: Raw events expire by retention, aggregates remain.

Entitlement checked at manifest issue

Situation: Subscriptions, rentals and free tiers must be enforced without making every segment request hit the database.

Choice: One canWatch function runs when the manifest is issued and the manifest URL is signed and short-lived.

  • Rejected: Check on every segment: expensive and uncacheable.
  • Rejected: Client-side gating only: trivially bypassed.
  • Consequence: Cancelled subscriptions lose access within the manifest TTL.
  • Consequence: True anti-piracy needs DRM, deferred and documented.

How the data is indexed

Indexes are chosen from the questions the app asks most often. Each line below names a table and the question its main index answers.

  • videos: (status, published_at DESC) — catalog browse of published titles.
  • renditions: (video_id, height) — build the master manifest in ladder order.
  • transcode_jobs: (status, run_at) where status = 'queued' — worker claim with SKIP LOCKED.
  • titles: (kind, available_from DESC) — browse by kind.
  • entitlements: (user_id, scope, ends_at) — canWatch lookup.
  • watch_events: unique (client_event_id) — drop duplicate beacons.
  • watch_progress: unique (user_id, video_id) — one row, upsert from the rollup.
  • catalog_rows: (row_key, position) — render a home row with one range read.

What Forge64 provides underneath

Forge64 matches your description to one of 12 reference architectures, writes the plan and data model into the project, generates the app, and runs a quality gate over the code before you see it. Each app gets its own Postgres database and sign-in with no per-user fee. Hosting on Forge Cloud and Forge Payments are rolling out.

This is a reference design for the category, not a promise that every item is generated today. Built-ins such as email, background jobs, file uploads and search are coming soon, so anything here that needs them is something you add yourself for now.

FAQ

What is the most important architecture decision for a video streaming app?
Adaptive bitrate streaming with a transcoding ladder. Transcode every upload into a ladder of renditions packaged as segmented CMAF (HLS + DASH) so the player switches quality per segment.
Do I have to make these decisions myself?
No. Forge AI plans them from your description and writes the decisions into the project as architecture records you can read and change.
What do the alternatives cost me?
For example, for "Object storage plus CDN, never the app server, for video bytes": Stream through Next.js routes: simple but caps scale and multiplies cost. Per-segment signed URLs: strong control but defeats caching.

Build your app with Forge64

One prompt to a running app with auth, database, hosting and payments. Start free, no credit card required.

Start building for free