Blog
Cost 7 min read

The real cost of self-hosting video: FFmpeg + S3 + CDN vs. buying

What an FFmpeg + S3 + CDN video pipeline actually costs: transcode compute, storage, dominant CDN egress, and the engineering hours nobody puts on the invoice.

rehelios

Engineering

“Just use FFmpeg” is true and also incomplete. FFmpeg is free, S3 is cheap per gigabyte, and CloudFront is a few clicks away — so a self-hosted video pipeline looks like it costs almost nothing until it’s actually carrying production traffic. The gap between “FFmpeg is free” and “our video infrastructure is cheap” is where most of the real cost hides.

Self-hosting video with FFmpeg, S3, and a CDN has three infrastructure cost lines — transcode compute, storage, and CDN egress — plus a much larger hidden line: the engineering time to build and operate signed URLs, captions, retries, webhooks, and on-call around that pipeline. At most catalog sizes, CDN egress dominates the infrastructure bill, not compute. A managed per-GB provider with free encoding collapses the compute line to zero and replaces months of pipeline engineering with an API call — but self-hosting still wins at genuinely extreme scale or with requirements an API can’t meet.

The infrastructure lines, one at a time

Transcode compute

Turning a source file into an adaptive bitrate ladder is the part everyone budgets for, and it’s usually the smallest line. Two ways to run it:

  • Managed transcode (e.g. AWS MediaConvert), priced per minute of output — roughly $0.0075–0.015 per minute per public AWS pricing at the time of writing, varying by resolution tier and output count in the ladder.
  • Your own EC2/GPU fleet, priced per instance-hour plus the autoscaling logic to spin workers up for a queue and down when it’s idle. Cheaper per minute at sustained volume, but now you’re also paying for the idle capacity you keep around for burst uploads, and for someone to tune it.

Either way, transcode compute is a real but bounded cost — it scales with how much video you ingest, not how much gets watched.

Storage

Object storage for source files plus every rendition in the ABR ladder (typically 3–5 renditions per video for HLS or DASH) is priced per GB-month and is rarely what breaks a self-hosted budget on its own. It’s the multiplier underneath the next line that matters more.

CDN egress — the one that dominates at scale

This is the line that surprises teams. Every rendition, every segment, every replay gets pulled through the CDN, and egress is priced per GB delivered, not per GB stored. A catalog that’s cheap to store can still generate a large bill once it starts getting watched — a popular video re-served thousands of times costs the CDN thousands of times over, while the storage cost for that same file barely moves. Past a modest scale, egress — not encoding, not storage — is what a self-hosted video bill is actually made of.

The costs nobody puts in the spreadsheet

The infrastructure lines above are the easy part to price. The engineering work to turn FFmpeg output into something a product can actually ship is where self-hosting quietly gets expensive:

  • Signed URLs and access control. Raw files behind a CDN are public by default. Building short-lived signed playback tokens (or a domain allowlist) — and rotating keys, handling clock skew, and revoking access — is its own project before video one goes live. See how signed playback tokens work for what that actually involves.
  • Captions and chapters. Auto-generating VTT/SRT captions in multiple languages means wiring a separate transcription step into the pipeline, storing the output alongside the video, and keeping it in sync when a source file gets replaced.
  • Webhooks and job orchestration. video.ready and video.failed events don’t exist until you build them — a queue, a state machine per video, retry logic for failed transcodes, and idempotency so a retried job doesn’t double-charge compute or double-write storage.
  • Monitoring and on-call. A transcode queue that silently backs up, a CDN cache-invalidation bug, a worker that OOMs on a 4K source file — all of it needs alerting, dashboards, and someone who owns the pager for a system that’s now core infrastructure, not a side project.
  • Retries and edge cases. Corrupt uploads, unsupported codecs, partial uploads that time out, duplicate submissions — every one of these is a code path a managed API already handles and a self-hosted pipeline has to discover in production.

None of this shows up in a per-minute or per-GB pricing calculator, and all of it is real payroll cost that keeps accruing after the pipeline ships, every time a new codec or edge case shows up.

Signed URLs

Token generation, rotation, revocation, clock skew.

Captions pipeline

Transcription step, multi-language storage, resync on re-upload.

Job orchestration

Queue, state machine, retries, idempotency.

Monitoring + on-call

Alerting, dashboards, someone holding the pager.

When self-hosting is genuinely the right call

None of this means “never self-host.” It means the decision should account for the full cost, and for some teams the full cost is still worth it:

  • Extreme, sustained scale, where the marginal cost of owning encoding and CDN infrastructure drops below any vendor’s margin — this is a small set of companies, usually ones already running significant infrastructure elsewhere.
  • Unusual requirements a general-purpose API doesn’t support: exotic codecs, custom DRM integrations beyond signed-token access, or processing steps specific to one content pipeline.
  • An existing media/infrastructure team that would otherwise be underutilized — if the skill set and the on-call rotation already exist, the marginal cost of adding video is lower than it is for a team building this from zero.

Outside those cases, the pipeline is usually being rebuilt from scratch by a team that will run it once.

What buying removes, not just what it costs

A managed API doesn’t just move the same cost lines to a vendor’s invoice — it removes some of them entirely. rehelios prices storage at $0.02 per GB-month and delivery at $0.005 per GB, with encoding free (a $1/month minimum), the same per-gigabyte model as Bunny Stream and the opposite of the per-minute billing used by Cloudflare Stream and Mux — the full provider comparison breaks down each billing model in detail. That structure changes the shape of the decision, not just the price:

  • The encoding line item disappears. Free encoding means transcoding a growing catalog never adds a cost that scales with ingest volume — a meaningful difference from Mux’s per-minute encoding charge. See why Mux charges to encode every minute for the mechanics of that comparison.
  • The pipeline disappears, not just the compute. POST /v1/videos or POST /v1/videos/import replaces the queue, the state machine, the autoscaling group, and the retry logic — not just the FFmpeg invocation.
  • Signed playback tokens and a domain allowlist ship on day one. No separate project to build access control before launch. (Worth saying plainly: signed tokens stop casual link-sharing and hotlinking, not screen recording — that distinction matters whether you build or buy.)
  • Captions, chapters, webhooks, and analytics are already wired. The work described above as “hidden cost” is the product, not an add-on.
npx @rehelios/cli upload ./lecture-042.mp4 --wait --json

That single call is the entire pipeline a self-hosted build spends weeks assembling: transcode, package to HLS, store, deliver, and return a playbackUrl. Full numbers are on the pricing section, and a column-by-column breakdown of how the billing models differ across providers is in video hosting API pricing compared by model.

The FFmpeg invocation was never the expensive part — the pipeline built around it is.

How to actually run the comparison

Model both paths honestly before deciding:

  1. Estimate GB stored and GB delivered per month at your current and projected-6-months scale — delivered volume, not stored volume, is what will move the self-hosted bill the most.
  2. Price transcode compute against your ingest rate, using a public per-minute range (MediaConvert) or your own instance-hour math, and remember it scales with uploads, not views.
  3. Price CDN egress separately from storage — this is usually the line that changes the outcome once a catalog gets real traffic.
  4. Put a number, even a rough one, on the engineering time for signed URLs, captions, webhooks, retries, and monitoring — a few weeks of engineer time is a real cost even if it never appears on a cloud invoice.
  5. Compare the total against a per-GB managed quote for the same stored and delivered volume, with encoding removed from the self-hosted side of the ledger entirely.

If you’re deciding whether to build this at all versus reach for an API, the SaaS decision guide walks through the same trade-off from the product side, and use cases for SaaS covers what the API path looks like once you’ve picked it.

Where this leaves the decision

Self-hosting isn’t free just because FFmpeg is. The infrastructure lines — compute, storage, and especially CDN egress — are real and measurable, and past a certain point egress alone can rival everything else combined. The line that rarely gets modeled honestly is engineering time: signed URLs, captions, retries, webhooks, and the on-call rotation to keep all of it running. A managed per-GB provider with free encoding doesn’t just quote a smaller number for the same pipeline — it removes the encoding line and the pipeline itself, leaving storage and delivery as the only two costs left to compare. For most teams outside the extreme-scale or unusual-requirements cases, that’s a smaller bill and a system nobody has to be paged for.

Put your first video live today

Create an account, upload a file, and have a fast, embeddable video live in minutes. Pay only for what you store and stream.