Free · 60 s Free AI-readiness audit See your site the way ChatGPT does.
Personal reply within one business day.
OWN PRODUCT · LIVE ↗

File handover · SaaS + client portal · 2026

A live, monetised SaaS, built and run by one person, from empty repo to launch in 3 weeks

Filyhost hands files to clients and gets files back: one private link out, one inbox link back, and no account for the client. It runs on Cloudflare’s edge, so the bill grows with stored gigabytes, not with visitors. Licences sell through Stripe on a rising price ladder, and a self-serve ad slot is open to advertisers.

Live at filyhost.com · built 31 Aug–21 Sep 2026 · 173 commits · numbers observed 2026-10-05

Open the live product: filyhost.com

01 · Before

Sending work is easy. Getting files back isn’t. The problem, as agencies live it.

Every agency knows the routine. Big files go through a transfer service, folders through a cloud drive, the rest by email. Then you chase the client for their logo, their copy, their photos, and the paid tools that would fix it put a sign-in wall in front of the very person you need files from.

How files change hands todaythe problem
sending
risk: One tool for big files, another for folders, email for the rest
receiving
problem: Chasing the client by email until something arrives
client
problem: Paid tools ask your client to create an account first
pricing
risk: Per-seat subscriptions for something you use twice a month
lifespan
risk: Links that live forever unless someone remembers to delete them
Brief to myself: one link out, one link back, no client account, files byte for byte, costs that follow storage only.

Building a client portal? First see what AI sees on your current site.Free AI-readiness audit · about 60 seconds · no email needed for the score.

02 · What I built

One link out, one link back Gold is a person acting. Teal is the edge at work.

The whole product is a single Worker in plain JavaScript, with no framework and no build step. The browser does the heavy lifting on the way in, and the edge streams on the way out, so neither a huge upload nor a 50 GB download ever needs a big server.

  1. Step 1 (you): Drop a folder, browser unzips & slices. Rejected here: Over budget (sign-ups pause first).
  2. Step 2 (automated): Multipart upload, parts checked on arrival.
  3. Step 3 (automated): Private link, expires on its own. Rejected here: Abuse report (kill switch, link gone).
  4. Step 4 (client): Client opens, no account.
  5. Step 5 (client): Sends files back, inbox link.
  6. Step 6 (automated): Email on arrival, to you.
  7. Step 7 (live): Resumable download, any byte, any size.
FIG 02 — A handover, end to end Two people act, the edge does the rest. Spend is guarded before it can run away, and abuse is shut down in place.
Filyhost home page on desktop: “Drag and drop to upload. Share your link.” with feature notes around the drop zone
Filyhost home page on a phone with the Choose files button and the sponsored slot
PLATE 01 — filyhost.com home, desktop and phone · live product, captured 2026-10-05
Filyhost inbox page: “Send the work. Get the work back.” with a diagram of one link between you and the client Filyhost licence page: a one-time price, not a subscription, and what Premium adds
PLATE 02 — Inbox links and the one-time licence, desktop · live product, captured 2026-10-05

03 · Who did what

Who did what Agents propose. A human approves.

  1. agent://researcher

    Mapped how agencies hand work over today and where each tool forces an account or a subscription.

    Never allowed to: choose the positioning.

  2. human://vegardHUMAN GATE

    Chose the product: one link out, one link back, a one-time licence instead of a subscription.

  3. agent://architect

    Drafted the storage model and a separate content domain, so an uploaded HTML file can never touch the app’s login.

  4. agent://builder

    Wrote the Worker, the browser-side slicer, the streaming download and the Stripe price ladder to spec.

  5. agent://tester

    Drove a real local server through upload, expiry and purge end to end, and caught a cron bug on its first run.

  6. human://vegardHUMAN GATE

    Measured the passkey library at 48% of the bundle and cut it. Evidence over features.

  7. agent://watcher

    Guards spend, runs 8 rate limiters and sends a daily ops email.

    Never allowed to: let the bill run away: new sign-ups pause first, then new uploads.

  8. human://vegardHUMAN GATE

    Ships every release from a clean, pushed commit. The deploy script refuses anything else.

04 · Results

Results, with receipts Every number dated, with its method.

Filyhost: results with method and date
NumberWhat it measuresHow it was measuredObserved
3 weeks✓ verified from empty repo to live, monetised SaaS git history 31 Aug–21 Sep 2026 2026-10-05
173✓ verified commits git history 2026-10-05
~0.1 s✓ verified of CPU to stream a 50 GB inbox download as TAR (vs ~91 s with ZIP's CRC-32) edge benchmark 2026-10-05
3 GB✓ verified resumable download verified on the edge (built for 50 GB) edge test 2026-10-05
8✓ verified edge rate limiters wrangler config 2026-10-05
8,695✓ verified disposable-email domains blocked, list refreshed weekly blocklist size 2026-10-05
$29 → $119✓ verified lifetime licence price ladder pricing config 2026-10-05
Not published Revenue and customer count own product; revenue figures stay private —

05 · Running costs

What it costs to run Storage, not traffic.

There is no server to keep warm. Files sit in object storage and are streamed from the edge, and streaming a 50 GB folder as a TAR archive takes ~0.1 s of CPU. So the bill follows stored gigabytes, not visitors. A budget guard watches spend: at the limit it pauses new sign-ups, and if spend keeps rising it pauses new uploads, while every existing link keeps working.

CPU for a 50 GB downloadstream a 50 GB inbox download as TAR (vs ~91 s with ZIP's CRC-32)
~0.1 s
Edge rate limitersabuse and cost protection, before any code runs
8
Disposable-email domains blockedrefreshed weekly, so free accounts stay real
8,695

06 · Ownership

What you would own If I built a portal like this for you.

  • The repositoryEvery line, with the release history: each live version is a pushed, diffable commit.
  • Your Cloudflare accountWorkers, object storage, database, rate limiters and cron, in your name.
  • Your Stripe accountPrices, the ladder logic and payouts go straight to you.
  • A separate content domainSo files your users upload can never reach your app’s login.
  • Ops email and runbookA daily report, the budget guard settings and the abuse kill switch, documented.
  • The lifecycle testsUpload, expiry and purge, driven end to end against a real server.

07 · What I’d build for you

A client portal or paid tool that runs itself, on your accounts

Client portals, file intake, quote tools, member areas: if your business sends things to clients or needs things back, I’ll build the portal with the same discipline. Payments, abuse handling and cost guards are part of the build, not phase two.

  • Portal or tool on your domain, your Cloudflare and your Stripe
  • No client accounts unless you want them; one-time codes instead of passwords
  • Budget guard and rate limits from day one
  • Optional MCP endpoint so your clients’ AI agents can use it

Not for you if an off-the-shelf tool already does the job. I’ll tell you so on the first call.

Not sure which fits? Book 20 minutes with me
08 · Under the hood The technical depth, for your CTO
Runtime
Cloudflare Workers in vanilla JavaScript, no framework, no build step: ~20,000 lines of source. R2 for files, D1 for accounts and links, the Cache API, three cron triggers.
Uploads
Zips are unpacked in the browser with DecompressionStream, never held in memory whole. Files are sliced and uploaded as multipart parts, each validated on arrival, so a bad upload fails fast instead of at 100%.
Downloads
A streaming USTAR archive instead of ZIP: a 50 GB inbox costs ~0.1 s of CPU to stream, where ZIP’s CRC-32 would burn about 91 s. Downloads resume at any byte offset with zero stored state (fixed-length stream plus ETag and If-Range). Verified at 3 GB on the edge.
Isolation
User content is served from a separate registrable domain, so uploaded HTML can never touch the app’s auth scope.
Abuse and limits
8 rate limiters, Turnstile, a weekly-refreshed blocklist of 8,695 disposable-email domains, and a kill switch that takes a reported link down in place.
Viral links
A link that goes viral costs one database read per data centre per minute, memoised in the Cache API, not one per request.
Payments
Stripe, with a lifetime licence that climbs $29 → $119 as live sales accumulate. Ads in the sponsored slot are bot-filtered and rotated by weight, rendered server-side with no layout shift.
Trade-offs
Passkeys were removed after measuring: one passkey library made up 48% of the Worker bundle (773 KiB). Evidence decided, not taste.
Launch film
The product film was rendered frame by frame from HTML, in 16:9 and 9:16, with a timed voiceover script.