Tutorials Build a Course Platform on Cloudflare Chapter 1

The Stack & The Bill — Build a Course Platform on Cloudflare for $0 (and What Changes at Scale)

Course PlatformChapter 1 of the Build a Course Platform on Cloudflare26 minMay 29, 2026Intermediate

You want to ship a paid course site. Videos behind a paywall, monthly subscription, the basics — like Teachable, Podia, Kajabi, or this site you're reading. The industry-standard way to build it pulls together half a dozen vendors and lands around $200/month before you have a single paying customer:

There is a budget version of the same site that runs on one vendor's free tier and only starts charging meaningfully when you've got real revenue. It's the stack this site runs on, and it's the subject of this series.

The whole thesis in one line: Cloudflare gives you almost every primitive you need (compute, storage, database, KV, CDN), R2 charges $0 for egress so video bandwidth is free, and the only external services you need are Stripe (payments) and Google OAuth (sign-in). One bill, one runtime, ten dollars a month until you're profitable.

This chapter is the architecture-and-bill overview. The next three chapters deep-dive each piece: streaming on R2 (Ch 2), auth + Stripe (Ch 3), and the paywall itself (Ch 4).

The Whole Stack in One Picture

Loading diagram…

Figure 1 — Yellow boxes are Cloudflare (one vendor, one dashboard, one bill). Purple boxes are external (Stripe for money, Google for identity). That's the whole stack.

Each box is a separate chapter or section in this series and is also taught from scratch in the web series — so when you hit something you don't know, you can drop down a level:

PieceWhat it doesFrom-scratch tutorial
WorkerYour "backend" — runs JS at the edge, responds to HTTPWeb Ch 8
D1SQLite at the edge — users, subs, progressWeb Ch 9 · Cloudflare Ch 3
R2Object storage for videos + images (the $0-egress hero)Web Ch 10 · Cloudflare Ch 2
KVGlobally-replicated key-value cache (sessions, hot reads)Cloudflare Ch 4
AuthGoogle OAuth → JWT session cookieWeb Ch 11 · Web Ch 12
StripeSubscriptions via Payment Links + webhookWeb Ch 13

The web series teaches each primitive in isolation. This series shows how they snap together for one specific product: a course site.

The Five Big Architecture Calls

These are the trade-offs that shape the budget. Each is a real, defensible decision — you can swap any of them for a heavier vendor later, but you don't have to start there.

1. R2 instead of Cloudflare Stream (the budget headliner)

For video hosting, Cloudflare offers two products and they're priced very differently:

R2 (object storage)Stream (managed video)
Storage$0.015 / GB-month$5 / 1,000 min stored / month
Delivery (bandwidth)$0 — always$1 / 1,000 min delivered
EncodingYou pre-encode locally (free, ffmpeg)Included
Adaptive bitrate (HLS)You ship MP4 or pre-render HLSAutomatic per-viewer
DRM / signed URLsYou build via Worker proxyBuilt-in

For a small library with modest viewership, R2 is one to two orders of magnitude cheaper. A 200 GB video library streamed 10 TB / month: ~$3 on R2 vs ~$15+ on Stream — but at TB-scale streaming or when you need real adaptive bitrate, Stream catches up and wins. Full breakdown with real numbers in Chapter 2.

2. Workers instead of Lambda + API Gateway

The serverless backend story everywhere else: AWS Lambda + API Gateway + CloudWatch. It works, but cold starts are real, debugging is its own job, and the bill at modest traffic is $30–60/month before you've done anything interesting.

Cloudflare Workers: 100,000 requests/day free, then $5/month for 10 million requests on the Paid plan, no cold starts (V8 isolates start in under 5 ms), and the same runtime for HTTP, cron, queues, and websockets. For a course site doing maybe a million requests a month, that's $5 flat. (For the full why-Workers-wins story see the Cloudflare series.)

3. D1 instead of a hosted Postgres

D1 is SQLite running on Cloudflare's edge. You get prepared statements, JOINs, transactions, migrations — actual SQL. The free tier covers 5 million row reads/day; the $5 Workers Paid plan unlocks much more.

Hosted Postgres (Supabase, Neon, RDS) is more powerful — better concurrency, JSONB, full-text, replication — but starts at $0–25/month idle and you're paying for an entire database server even when nobody's signed in. For a course site whose schema is "users, subscriptions, video progress, articles," D1 is plenty.

The exit ramp from D1 to Postgres later is small if your schema is sane. Don't over-commit to D1's quirks early; just don't reach for Postgres before you need it.

4. Stripe Payment Links instead of Apple IAP / a heavier checkout

If your courses are sold via a website, you can take payments through Stripe directly. Stripe charges around 3% per transaction. If you ever distribute through Apple's App Store, IAP forces you to use Apple's billing — about 30%. On a $10/month subscription, that's the difference between netting $9.70 and $7.00 per subscriber per month. Over a year and a thousand customers, that's a real five-figure number.

This site (and every course platform on the web) uses Stripe Payment Links — a hosted checkout URL Stripe gives you; no PCI scope, no custom UI. The Worker's only job is verifying Stripe's signed webhook on subscription events and updating D1. (See web Ch 13 for the from-scratch walkthrough, and Chapter 3 of this series for the course-specific integration.)

5. Google OAuth instead of Auth0 / Clerk / Cognito

You could pay $35+/month for Auth0 or Clerk and never write a line of auth code. Or you could implement Google OAuth in a Worker in roughly 100 lines — redirect to Google, get back an id_token, verify it, mint your own JWT session cookie. Free, no vendor, no rate limits, no migration headache later.

Auth0's pitch is "social logins, MFA, enterprise SSO, magic links" — every additional auth method you want. For a course site where everyone signs in with Google, none of that is in the critical path. (See web Ch 11 and Ch 12 for the foundation, and Chapter 3 for the course-platform wiring.)

The Bill at Three Scales

Numbers are 2026 list prices, rounded for clarity. Confirm on each vendor's pricing page before betting real money on them.

Hobbyist — 50 users, 50 GB of video, ~500 GB delivered / month

Line itemCost / month
Workers Free (under 100k req/day)$0
R2 storage 50 GB (after 10 GB free)~$0.60
R2 egress (always $0)$0
D1 free tier$0
KV free tier$0
Google OAuth$0
Stripe (% of revenue, not flat)~3% of subs
Fixed monthly≈ $1

Real product — 5,000 users, 200 GB of video, 10 TB delivered / month

Line itemCost / month
Workers Paid ($5 base + small overage)~$5
R2 storage 200 GB~$3
R2 egress 10 TB (still $0)$0
D1 (included in Workers Paid for most usage)~$0
KV reads/writes~$1
Stripe (~3% of subs)variable
Fixed monthly≈ $10

Scaling — 50,000 users, 1 TB of video, 100 TB delivered / month

Line itemCost / month
Workers Paid + overage~$15
R2 storage 1 TB~$15
R2 egress 100 TB (still $0)$0
D1 reads/writes overage~$10
KV overage~$5
Cloudflare Stream (if you've switched for adaptive bitrate)~$50–150
Stripe (~3% of subs)variable
Fixed monthly≈ $50–200

Graduation Triggers — When to Swap Each Piece

You shouldn't pre-emptively pay for the heavier vendor. But you should know the trip-wires:

PieceSwap to…When
R2 + MP4Cloudflare StreamYou need adaptive bitrate (HLS) per-viewer at TB-scale delivery, or DRM, or signed-URL playback tokens out of the box
D1Hosted Postgres (Neon, Supabase)JOINs on tens of millions of rows are slow; you need JSONB / full-text / read replicas
KV sessionsD1 sessions table (or Durable Objects)You need to server-side-revoke a logged-in session immediately (KV is eventually consistent)
Worker-rendered pagesNext.js on Workers (OpenNext) or PagesYou want React, SSR, and a real frontend framework (this is in fact what simpleappshipper.com does)
Google OAuth onlyAuth0 / ClerkYou need 5+ social providers, magic links, MFA, enterprise SSO — none of which a course site usually needs
Stripe Payment LinksStripe Checkout custom integrationYou need cart logic, multiple line items, custom upsells, gift purchases

The pattern: start at the leftmost column for everything; promote a single piece when a specific feature it can't do becomes blocking. Most successful indie SaaS lives entirely in the left column.

What You Actually Need to Sign Up For

All three of the external accounts have free tiers. None requires a credit card to start hacking.

  1. Cloudflare — covers Workers, R2, D1, KV, Pages, DNS. One account, no card needed for the Free plan.
  2. Stripe — Test-mode keys work without bank approval; you can build the whole subscription flow before they ever know you exist.
  3. Google Cloud Console — for an OAuth Client ID. Free tier covers any course site's identity volume.

That's it. Three signups, zero dollars, and you've got every account you need to build the rest of this series end-to-end.

Mental Model — Three Sentences

  1. The whole stack is one vendor (Cloudflare) plus two external must-haves (Stripe for money, Google for identity) — that's why the bill stays small.
  2. R2's $0 egress is the budget headliner — video bandwidth, the line item that crushes everyone else's stack, is free here.
  3. Every box has a defensible "graduation trigger" — start at the cheap option for everything, and promote one piece only when a specific feature it can't do is blocking you.

Try It Yourself (20 Minutes)

  1. Open three browser tabs and create accounts: Cloudflare, Stripe (test mode), Google Cloud Console. All free.
  2. In the Cloudflare dashboard, create one R2 bucket, one D1 database, and one empty Worker. (Or run wrangler init locally.) You now have the entire backend provisioned.
  3. In Stripe, create a test Product with a recurring price and copy the Payment Link URL. That's your subscription button.
  4. In Google Cloud, create an OAuth 2.0 Client ID for a "Web application" and add http://localhost:8787/auth/google/callback as a redirect URI. Save the client ID and secret.
  5. Look at your bill projection on each dashboard. Notice it's $0.

Where This Lands in the Series

You've now got the full architecture map and a defensible cost model. The next three chapters fill in the implementation:

← Series OverviewCh 2: Streaming Video on R2 — the $0-Egress Budget Workaround
CloudflareCloudflare Feature FocusFocused Cloudflare tutorials for Workers, R2, Stream, Durable Objects, and edge deployment.Production WebProduction Web Apps SeriesProduction patterns for web apps: caching, rate limiting, webhooks, queues, cron jobs, and idempotency.DeliveryModern Delivery PipelineCI/CD, review, runner, and deploy workflows for teams shipping apps and websites safely.

Ship your apps faster

When you're ready to publish your Swift app to the App Store, Simple App Shipper handles metadata, screenshots, TestFlight, and submissions — all in one place.

Try Simple App Shipper
5 free articles remainingSubscribe for unlimited access