YouTube clone
A YouTube clone is a video site you host yourself: it accepts uploads, stores the files, keeps the metadata, and streams them back on demand. The player is the easy part — what decides whether it works, and what it costs, is the three layers underneath it.
What you are actually building
Strip away the interface and there are four pieces, and only one of them is visible:
- An upload path — receives a large file and puts it somewhere durable.
- Object storage — the bytes themselves, addressed by key.
- A metadata store — title, duration, size, when it was added. This is what your listing page renders and what search works against.
- A playback endpoint that speaks HTTP Range — without it, seeking breaks.
Most tutorials start with the player because it demos well. It is also the piece browsers largely handle for you: <video> already buffers, seeks and adapts. What breaks in production is invisible — an upload that dies at 90%, a bucket that quietly becomes a public file host, a seek that re-downloads the entire file.
Range requests are not optional
When you drag the playhead to the middle of a video, the browser does not re-download what came before. It sends Range: bytes=2097152- and expects a206 Partial Content back, with Content-Range telling it where this chunk sits in the whole.
Serve video without Range support and seeking either does nothing or forces a full download first — which on a 50 MB file is the difference between instant and unusable. TubeForge parses the header, reads just that slice out of R2, and returns:
HTTP/1.1 206 Partial Content
Content-Range: bytes 2097152-5242879/5242880
Accept-Ranges: bytesThe tradeoff worth knowing: every Range request is a separate Worker invocation, and the free plan allows 100,000 per day. See the cost breakdownfor where that becomes the binding constraint.
Egress is the line item that decides everything
Storage is cheap and predictable — 10 GB of video costs pennies a month, and grows only as fast as you upload. Outbound traffic is different: it grows with every view, with no ceiling. A video nobody watches costs nothing to store; a video that goes viral can cost more in a day than the file cost all year.
| Serving 50 MB video × 1,000 views (50 GB out) | Egress cost |
|---|---|
| Cloudflare R2 | $0.00 |
| Amazon S3 (us-east-1) | ≈ $4.50 |
| Self-managed VPS bandwidth | ≈ $0.50 – $2.50 |
R2 charges no egress fee at all; the S3 figure assumes roughly $0.09/GB and the VPS range typical metered bandwidth. Providers change these numbers — checkR2 pricingand S3 pricingbefore you budget against them.
This single difference is why a video project on R2 stays free as it grows, while the same project on S3 starts generating a bill the moment anyone watches.
What TubeForge gives you
TubeForge is an open-source reference implementation of exactly those four pieces, on Cloudflare R2 + D1 + Workers with an Astro front end. It is deliberately small enough to read in an afternoon:
- Streaming uploads. The request body is piped straight into R2 and never parsed into memory. That matters because Workers bill CPU time, not wall time — waiting on IO is free, but decoding a 50 MB body is not. Verified in production: a 50 MB PUT lands intact well inside the free plan's CPU budget.
- A private bucket. Every read goes through a Worker. The bucket is never public, so the site cannot be turned into a free video host by someone scraping URLs.
- Server-rendered pages. The listing and watch pages are rendered on the server, so a crawler sees real entries rather than an empty shell waiting on JavaScript.
- Deletion by token. The delete token is returned once at upload and kept in your browser; the server never exposes it in any listing.
Limits to know before you start
| Limit | Value |
|---|---|
| Per upload | 95 MB |
| Total storage | 9 GB |
| Video formats | MP4, WebM |
| Thumbnails | JPEG, PNG |
| Worker requests | 100,000 / day (free plan) |
The 95 MB ceiling is not arbitrary: the Workers request body cap is 100 MB, and TubeForge reserves headroom for headers and multipart overhead. Going larger means changing strategy — a presigned URL so the browser uploads directly to R2, bypassing the Worker body limit entirely.
Where to go next
Fork and deploy itWhat it costs to runEstimate a file's sizeTry an upload