Cost economics & vendor lock-in
Today — the £/month at v0
Before a single Sport Head registers, what is the bill? Mostly zero, but with a couple of footguns hiding in the "free" column.
The current stack runs almost entirely on free tiers. That is deliberate and sensible for pre-launch. The risk is not the bill today — it is that several free tiers have operational limits (build minutes, deploys per day, request-per-day caps) that bite well before any cost limit does.
| Line | Tier today | Free ceiling (2026) | £/mo at v0 |
|---|---|---|---|
| Cloudflare Pages (sporthead-id, sporthead-com) | Free | 500 builds/mo, unlimited bandwidth, 100 custom domains/project | £0 |
| Cloudflare Workers (reserve, federation-router) | Free | 100k req/day, 10ms CPU/req | £0 |
| Cloudflare D1 (reserve worker) | Free | 5GB storage, 5M rows read/day, 100k writes/day | £0 |
| Cloudflare KV (federation theme cache) | Free | 100k reads/day, 1k writes/day, 1GB | £0 |
| Cloudflare Turnstile | Free | 1M widget calls/mo | £0 |
| Supabase (sporthead-id project) | Free | 500MB DB, 1GB Storage, 2GB egress, 50k MAU, pauses after 7d inactivity | £0 |
| GitHub Actions | Free (public) / 2000 min on private | 2000 min/mo private repos | £0 |
| GitHub Packages (planned, private) | — | 2GB storage, 1GB bandwidth/mo on free | £0 |
| Domain registrations (sporthead.id, .com, federation vanity) | — | — | ~£8 |
Bottom line: ~£8/mo, dominated by domain renewals. Two non-obvious traps: (1) Supabase free-tier projects pause after 7 days of no API activity — fine for dev, fatal the day a federation partner pokes at a portal you forgot existed; (2) GitHub Packages private bandwidth is metered the moment a consumer (SHOTclubhouse repo, CI, contractor laptop) starts pulling tagged versions of @sporthead/identity. Flip Supabase to Pro and GitHub to paid before launch, not after the first incident.
Bill curves at 5k / 50k / 500k Sport Heads
Where do the curves bend? Per-Sport-Head per month: ~5 sign-ins, 20 page views, 30 RPCs, 10 trait fetches, 1 avatar render. Two federations (SLFA + WAB) at 50k combined members, scaling proportionally.
| Line | 5k (launch) | 50k (year 1) | 500k (year 2-3) |
|---|---|---|---|
| Supabase tier | Pro $25 | Pro $25 + ~$10 compute + ~$15 egress overage | Team $599 floor, likely Enterprise — model £3-6k/mo |
| Supabase MAU billing | within Pro 100k MAU | within Pro 100k MAU | 500k MAU × $0.00325 over 100k = ~$1,300 above tier |
| Cloudflare Workers req | ~5M/mo — free | ~50M/mo — Paid $5 base + $0.30/M over 10M = ~$17 | ~500M/mo — ~$155 |
| Cloudflare D1 (reserve + audit logs) | Free | ~$2-5 reads, ~$1 writes | ~$30-60 |
| Cloudflare KV (theme lookup) | Free | Free at ~10M reads | Paid $5 + $0.50/M reads over 10M = ~$25 |
| Trait PNG bandwidth (CF Pages or R2) | Negligible | ~150GB egress, CF free | ~1.5TB/mo through CF — still free if from Pages/R2, not Workers |
| VC issuance storage (Supabase or R2) | ~5k blobs ~5MB | ~200k blobs ~200MB | ~2M+ blobs ~2-5GB on R2: ~$0.075 |
| GitHub Packages bandwidth | ~£0 (1-2 consumers) | £5-20 if multiple federations pull weekly | £20-100, depends on cache hit rate |
| Turnstile | Free | Free (well under 1M) | Free or Enterprise — verify at scale |
| Estimated total £/mo | £25-40 | £60-120 | £4-8k (Supabase-dominated) |
Curve bend #1: Supabase 100k MAU
Pro tier includes 100k MAU. Cross that and you pay $0.00325/MAU on top. At 500k that's ~$1,300/mo extra — small. The real bend is when DB compute or egress forces you off Pro entirely. Team is $599 and includes SOC2 reports federations may demand. Enterprise is a sales call with no anchor number.
Curve bend #2: Trait PNG bandwidth
99 PNGs × 100-500KB × every page render is the largest data flow. Served from CF Pages or R2 it is effectively free. Served from a Worker (e.g. to gate access or rewrite URLs) every byte counts against Workers paid tier. The mooted traits.sporthead.id CDN only saves money if it stays a static origin with cache headers — adding a Worker shim inverts the economics.
Curve bend #3: D1 row reads
D1 paid is $0.001/1k reads. Cheap until somebody writes a worker that does row-level lookup on every request without caching. The federation-router stub is exactly that pattern — every cold cache hit is a D1 read. Plan the KV cache layer before the second federation goes live.
The "built not bought" OIDC math
ADR-0006 chose to build OIDC on Workers to avoid per-MAU vendor cost. The red-team disputed the build estimate. Here is the run-rate math on both sides.
| Option | 5k MAU | 50k MAU | 500k MAU | Notes |
|---|---|---|---|---|
| Build on Workers (current plan) | ~£20 infra + 6mo eng amortised | ~£60 infra | ~£500 infra + ongoing maintenance | Infra cheap; real cost is engineering + ongoing security tax |
| WorkOS AuthKit | 1M MAU free, then $2,500 base — so £0 at 5k | Still free tier or low Connect bundles ($125/mo for SSO) | Enterprise — model £2-5k/mo | Best-in-class B2B, slightly awkward for B2C identity |
| Clerk | Free under 10k MAU | $25 + 40k × $0.02 = $825/mo (~£660) | ~$8,000/mo (~£6,400) | Per-MAU brutal at scale; great DX at small scale |
| Auth0 B2C | $228/mo first 1k MAU then tiers | ~$1,200/mo | Enterprise; historically £8-15k/mo at 500k | Cautionary tale that anchors this debate |
| Hanko (self-host OSS) | ~£20 infra | ~£60-100 infra | ~£300-500 infra | You own ops; passkey-first; less mature than paid options |
| Ory Hydra (self-host OSS) | ~£30 infra | ~£100 infra | ~£500-1,000 infra | Battle-tested OIDC; you still own JWKS rotation, refresh tokens, etc. |
The honest read: the build-vs-buy math is not as flattering as ADR-0006 implies. At 50k MAU, WorkOS is plausibly cheaper than the fully-loaded cost of building (one senior engineer-month is ~£10-15k; 6 months is £60-90k; that's 8-12 years of WorkOS bills at the 50k tier). The build only "wins" if (a) engineering really is 1-2 weeks, which the red-team disputes, and (b) ongoing security tax is zero, which it never is. The right comparison: not "infra bill A vs infra bill B + vendor fee" but "infra bill A + 6 months critical-path delay + ongoing on-call vs vendor fee".
The strongest argument for build is product control over the PIN-as-primary-factor flow and identity-as-domain-noun branding — neither WorkOS nor Clerk make that easy without heavy theming. That is a real reason. "Cheaper" is not.
Hidden costs — what isn't in the bill
Engineering time on undifferentiated heavy lifting
JWKS key rotation, refresh-token rotation + replay detection, PKCE downgrade defence, token revocation lists, session pinning. None of this ships product features. At ~£500/day fully-loaded, every two-day rabbit hole on a known-solved problem is £1k that did not buy a Sport Head.
Annual pentest £10-25k/yr
OIDC + VC issuance is a meaningful attack surface. Reputable London/UK testing house: £10-25k for a focused 5-day engagement on auth + credential surface. Budget annually from the moment OIDC is live.
On-call
Red-team flagged single-person on-call risk. PagerDuty for a small team is ~£15/user/mo; real cost is the human one. Two-person rotation minimum; expect a £5-15k/yr hit in retention and weekend pay/comp time once incidents start.
SOC2 / ISO27001 £20-50k/yr
The moment a federation procurement asks "are you SOC2?", you have ~6 months to be. SOC2 Type 2 via Vanta/Drata: £8-15k/yr platform + £15-30k audit. ISO27001 similar. Plan £20-50k/yr blended once any federation customer is paying.
DPIA + ICO consultation
Identity, children-adjacent (sport youth federations), biometrics-ish (helmet rarity tied to identity) is exactly ICO-published-guidance territory. Solicitor-led DPIA: £5-15k once; lower ongoing.
Two-founder bus factor
Jonny and Liam are the only operators of every system documented here. Replacing either is a senior hire at £80-120k fully-loaded plus 3-6 months ramp. A known liability on the cost ledger.
Vendor lock-in matrix
Score each vendor: difficulty of leaving, data extractability, code portability. 1 = trivial to swap, 5 = effectively permanent.
| Vendor | Difficulty to leave | Data extractability | Code portability | Notes |
|---|---|---|---|---|
| Cloudflare Pages | 1 | n/a (static) | 1 | Any static host; trivial. |
| Cloudflare Workers (Hono) | 2 | n/a | 2 | Hono runs on Node, Bun, Deno, Lambda. Watch for CF-specific APIs leaking into business logic. |
| Cloudflare D1 | 2 | 2 | 2 | SQLite-compatible — dump and restore anywhere. |
| Cloudflare KV | 3 | 3 | 3 | No SQL semantics; enumerate keys via API to export. Re-platforming means picking Redis/Upstash/DynamoDB and rewriting access patterns. |
| Cloudflare Turnstile | 1 | n/a | 1 | reCAPTCHA / hCaptcha drop-in. |
| Supabase Auth | 5 | 3 | 3 | The big one. Passwords are bcrypt-hashed (extractable), but PIN hashes, JWT format, refresh-token rotation behaviour, and GoTrue endpoint contract are proprietary. Migrating auth means dual-running both systems until every user re-authenticates. Expect a 12-month tail. |
| Supabase Postgres | 2 | 5 | 4 | It is Postgres. pg_dump moves you to RDS/Neon/self-hosted in an afternoon. RLS policies are SQL. |
| Supabase Storage | 2 | 4 | 3 | S3-compatible API; move the bucket, repoint clients. Storage RLS layer needs re-implementing. |
| GitHub Actions | 3 | n/a | 3 | YAML port to GitLab CI / Buildkite / Jenkins is annoying but mechanical. |
| GitHub Packages | 3 | 2 | 3 | URLs are GitHub-specific. SHOTclubhouse points at npm.pkg.github.com; moving to private NPM means coordinated flips. |
did:web:sporthead.id | 5 | n/a | n/a | Permanent. Every VC issued points to this domain. Changing the issuer DID invalidates every credential in the wild. Lock-in to a domain name. Treat sporthead.id renewal as critical infrastructure with explicit auto-renewal monitoring. |
The 100k MAU "wall" scenarios
Inflection points where the architecture or the bill needs rethinking.
| Cohort | Realistic £/mo | What changes architecturally |
|---|---|---|
| 10k MAU | £60-150 | Supabase Pro confirmed. CF Workers paid. Light caching matters but nothing on fire. |
| 100k MAU | £1-3k | Supabase Team ($599) is the floor for SOC2 reports federations will demand. Read replicas discussed. GitHub Packages bandwidth metered. Annual pentest line item appears. |
| 1M MAU | £10-30k | Supabase Enterprise (custom; expect £5-10k+). CF Workers paid usage meaningful. Dedicated SRE hire becomes plausible. Compliance overhead £30-60k/yr blended. |
Unit economics: at 100k MAU with ~£1.5k/mo bill, that's ~£0.18/Sport Head/year. At 1M MAU with £20k/mo, £0.24/SH/yr. Infrastructure scales sub-linearly — good news. Operational and compliance cost scales super-linearly — every 10× increase brings a new compliance regime, pentest scope, threat model. Budget on operational headcount, not vendor invoices, above 100k MAU.
For the business to support this load, revenue per Sport Head needs to be ~£1-2/yr minimum — not from the Sport Head (free) but from the federation paying for the portal. The unit math sits squarely on the federation deal.
"What if we ditched X" — option pricing
Drop Cloudflare for AWS
Lambda + S3 + CloudFront + DynamoDB. Similar bill at small scale, materially more expensive at edge-heavy scale (Lambda@Edge pricier than Workers). Operational complexity goes up. Lock-in shifts to AWS, which is at least equally sticky. No reason unless a federation explicitly demands AWS.
Drop Supabase for Neon + Lucia / Better Auth
Neon cheaper than Supabase Team at comparable scale (~£100-300 at 100k MAU). Lucia/Better Auth give Postgres-native auth without vendor lock. Trade: no Storage (need R2), no Realtime, no GoTrue — you write glue. Realistic gain: ~£300-500/mo at 100k MAU, paid for with 1-2 engineer-months. Worth considering at 100k inflection, not before.
Replace OIDC plan with WorkOS
£0-200/mo at 5k MAU, scaling. Removes 6 months of engineering from critical path. Pros: ship federation portal faster, get SOC2-able auth for free, stop carrying on-call risk on homemade OIDC. Cons: lose product control over PIN-first flow; brand surface is theirs not yours. Revisit the ADR-0006 decision with this on the table.
Move VC signing to AWS KMS + R2 issuer log
KMS is ~£0.80/key/mo + £0.03/10k operations. R2 ~£0.01/GB-mo, no egress fees. Real key custody (HSM-backed), proper audit log. Adds AWS as a vendor — small, focused, low lock-in surface. Cost at 500k MAU: ~£20-50/mo. Most defensible single change here.
The honest unit economics
Federation pays SHOT for a portal. Members are free. Does the federation cheque cover infrastructure + engineering + compliance?
| Scenario | Revenue | Direct cost (infra + share of ops) | Margin band |
|---|---|---|---|
| 2 federations × £20k = £40k ARR (year 1) | £40k | ~£5k infra + ~£100-150k eng + ~£10-20k compliance = £115-175k | heavy loss — funded by runway |
| 10 federations × £20k = £200k ARR | £200k | ~£20-40k infra + £150-200k eng + £30-50k compliance = £200-290k | break-even to thin loss |
| 25 federations × £25k = £625k ARR | £625k | ~£100-150k infra/compliance + £250-300k eng = £350-450k | ~30-40% margin, healthy |
Margin gets healthy only at ~20+ federations. Below that, the business is funded by runway, not federation revenue — fine for a launch year but should be on Jonny and Liam's whiteboard as the explicit thing the next 24 months has to deliver. Biggest swing factor is engineering cost, not infrastructure — which is exactly why the "build vs buy" decisions matter more than the £/mo numbers on any vendor invoice.
Verdict
Healthy at the bottom, fragile at the operating-cost middle
The vendor bill itself is not the problem at any plausible 24-month scale — £5k/mo even at 500k MAU is rounding error against a £600k ARR target. The three expensive surprises are: (1) the "we built OIDC to save money" estimate is the wrong frame — 6 months of senior engineering is worth ~10 years of WorkOS bills, and on-call cost is permanent; (2) SOC2/ISO/pentest/DPIA together will be £30-60k/yr the moment federation procurement is serious, and that line item is currently invisible; (3) the did:web domain is the only permanent lock-in in the stack and is currently treated as a regular domain rather than critical infrastructure. The right move: reopen ADR-0006 with WorkOS / Hanko on the table, move VC signing to KMS before launch, get sporthead.id on locked auto-renewal with monitoring this week, and put the compliance line in the runway model now rather than discovering it during the first federation procurement.