← StraightPath

Sending large files without a server: what actually works

Moving a 20 MB document is solved. Moving 20 GB — a dataset, a video project, a raw disk image, a folder with 600 files in it — is where most "file sharing" options quietly stop working. This is an honest map of the four ways to do it from a browser in 2026, what each one costs, and where browser peer-to-peer genuinely loses.

The short version

If both parties can be online at the same time and neither wants the file stored on a third-party server, transfer it browser-to-browser over WebRTC: no upload, no download-again-from-the-cloud, no quota, no expiry date on the link. If the recipient will show up hours or days later, you need storage, and a server is the right tool — just know that is what you are paying for.

The four options, compared

MethodWhere the bytes livePractical ceilingWhat it costs you
Email attachmentBoth mailboxes, plus every relay in between25 MB, sometimes 10 MBNothing else — that is why the ceiling is so low
Cloud drive / transfer service linkThe provider's servers, until the link expires2–200 GB depending on planAccount, upload time, provider egress cap, and a third party holding the file
Object storage with a presigned URLYour own bucketEffectively unlimitedYou run a backend, you pay egress per download, you manage credentials
Browser peer-to-peer (WebRTC)Nowhere in betweenSender's disk and the recipient's diskBoth sides must be online for the whole transfer; sender's upload bandwidth is the ceiling

Why the browser can do this at all now

Five APIs landed and made the fourth option real rather than a demo:

"Serverless" still needs somewhere to exchange phone numbers

Two browsers on the public internet cannot find each other from nothing: something has to carry the session description and the ICE candidates. That is signalling, and it is the only part of the flow that touches a third party. The options are a WebSocket relay you run yourself, or a public one. StraightPath uses public Nostr relays — a message-propagation network designed for exactly this shape of small, ephemeral, unauthenticated-but-keyed traffic — plus public STUN resolvers and opt-in TURN relay.

Crucially, signalling carries no file bytes. And the encryption key is not in it either: the key lives in the URL fragment (#k=…), and browsers never transmit fragments to servers, never put them in Referer, and (in this app) never write them into the address bar or history. Whatever observes the signalling sees a room id and ciphertext.

Where peer-to-peer is worse, stated plainly

Step by step: a 10 GB folder, browser to browser

  1. The sender opens the page and drops the folder. Nothing is uploaded — the browser reads the files locally and starts hashing them into a Merkle tree, block by block.
  2. The page produces a link and a QR code. The link is the whole delivery: room id plus key.
  3. The recipient opens it. Their browser decrypts the manifest with the key — file names, sizes and the expected root are all sealed, so an observer learns nothing — and starts requesting blocks.
  4. Blocks stream in, are decrypted, and are written to OPFS immediately. Memory stays flat; disk usage grows by exactly the amount received.
  5. At the last byte the recipient recomputes the entire Merkle root locally and compares it with the sealed one. Verification is a full re-read, deliberately not trusting the receive path that produced the bytes.
  6. The recipient exports to a real folder. If they close the page halfway, reopening it asks whether to fill the remaining blocks or delete what arrived and start over.

Troubleshooting

The recipient sees nothing happening.
Nine times out of ten the sender closed the tab. The offer only lives as long as the page that made it.
It connects but crawls.
Check the sender's upload speed first — that is the ceiling. If both ends are on office or carrier NAT, enable TURN under Advanced settings and accept the slowdown in exchange for a working path.
Verification failed.
The client refetches the affected blocks a bounded number of times and then stops and says so, rather than looping forever. A genuine failure means either the sender's file changed mid-transfer (re-share it) or something corrupted blocks in flight — the Merkle root exists precisely so this cannot pass silently.
It is eating my disk.
Received blocks are real bytes on your disk until you export and clean up. A good client shows you the number and gives you a button that gives the space back.
Can I paste the link into a group chat?
Yes, but treat it as a secret: the link contains the key. Anyone who opens it while the sender is online can receive the file. Short-lived offers and a private channel are the mitigation.

Which one should you use

Under ~25 MB and one recipient: email, honestly. Recipient appears later, or you need a permanent link: a cloud drive, and pay the storage. You are building infrastructure and want programmatic control: object storage with presigned URLs. Both parties online, file is large, and you would rather the bytes went directly: browser peer-to-peer — which is what StraightPath is for.