Streaming CDN

Drop: how we send files of any size straight between browsers, torrent-style, over WebRTC

Updated 2026-11-03

Drop is a free tool at streaming-cdn.ewin888.com/drop. You open a room, scan its QR code on another device, and send files or chat in real time. It needs no sign-up and no app, and there is no size limit on a direct connection. We built it with the same browser real-time stack we run for live video, and this article explains how it works. Every number below is a constant in the shipping code.

What it does

1. The server only introduces the browsers

Two browsers cannot open a WebRTC connection until they have swapped an SDP offer, an answer and their ICE candidates. Drop's server does exactly that and nothing else: each room is a small WebSocket signaling room that relays those messages and keeps the member list. Chat messages and file bytes never pass through it. A signal is capped at 64 KiB and a socket at 400 messages per 10 seconds, so the room cannot be used as a message bus.

Each pair of members opens one RTCPeerConnection with two negotiated data channels: channel 0 carries chat and control messages as JSON, and channel 1 carries file bytes. A newcomer gets the room's chat history (up to 300 messages) from a member who is already there, not from the server.

2. Direct first, relay only when it must

The page first asks only for discovery (STUN) servers, which tell each browser its public address. That is enough for most pairs: two devices on the same Wi-Fi, or on most home and mobile networks, connect directly. If no direct path comes up within 6 seconds, the page asks for relay (TURN) credentials and retries through the relay.

DirectRelayed
PathDevice to deviceThrough an encrypted relay
Who can read itOnly the two browsers (DTLS)Only the two browsers; the relay forwards encrypted packets it cannot decrypt
File sizeNo limit200 MB per file
AllowanceNone8 relay credentials per network address per day, each valid one hour

Relayed traffic is the only part of Drop that costs us bandwidth, which is why it has an allowance. The interface shows which link each member is on, and tells you to move both devices onto the same Wi-Fi if you need to send a large file over a relayed pair.

3. Sending fast without running out of memory

RTCDataChannel.send() never blocks: it queues. Push a 4 GB file into it in a loop and the tab runs out of memory. Drop sends 64 KiB chunks and stops when the channel's bufferedAmount passes 4 MB, then resumes when it drains below 1 MB:

const CHUNK = 64 * 1024;
const HIGH = 4 * 1024 * 1024;
const LOW = 1024 * 1024;

channel.bufferedAmountLowThreshold = LOW;

async function sendBlob(channel, blob) {
  for (let offset = 0; offset < blob.size; offset += CHUNK) {
    if (channel.bufferedAmount > HIGH) {
      await new Promise((resolve) => channel.addEventListener("bufferedamountlow", resolve, { once: true }));
    }
    channel.send(await blob.slice(offset, offset + CHUNK).arrayBuffer());
  }
}

blob.slice() reads from disk only the bytes being sent, so the sender never loads the whole file either.

4. Pieces, hashes and the swarm

Sending a whole file from one person to everyone else would put the full upload on the sender's connection. So Drop shares files the way BitTorrent does. Before sharing, the page cuts the file into pieces of at least 1 MiB, using no more than 2,048 pieces per file, and hashes each one with SHA-256 in the browser. The file's announcement carries a root: SHA-256 over all the piece hashes, in order.

async function describe(file, pieceSize) {
  const hashes = [];
  for (let offset = 0; offset < file.size; offset += pieceSize) {
    const piece = await file.slice(offset, offset + pieceSize).arrayBuffer();
    hashes.push(new Uint8Array(await crypto.subtle.digest("SHA-256", piece)));
  }
  const joined = new Uint8Array(hashes.length * 32);
  hashes.forEach((hash, i) => joined.set(hash, i * 32));
  const root = new Uint8Array(await crypto.subtle.digest("SHA-256", joined));
  return { hashes, root };
}

5. Downloads live on disk, not in memory

A phone cannot hold a multi-gigabyte download in memory. Drop writes pieces into the browser's origin private file system (OPFS) from a dedicated worker, using synchronous access handles, the one OPFS write path that every current engine supports. Alongside the data it stores a small record of which pieces it holds, one bit per piece.

6. Keeping a phone transferring when the screen locks

Mobile browsers suspend a page when the screen locks, which would stop every transfer. Drop does two things. While files are moving, it holds a Screen Wake Lock so the idle timer does not lock the phone. A background mode keeps the room running even when the screen is locked, on iPhone too. Background mode works by playing a looping silent audio track, because a page that is playing audio is allowed to keep running. The trade-off is that music in other apps pauses while background mode is on, so it can be switched off.

What Drop is not

Try it

Open streaming-cdn.ewin888.com/drop, create a room, and scan the code with your phone. It works in current Chrome, Edge, Firefox and Safari. Drop is free, and the page carries a small note about our main product, which is low-latency live streaming. The same WebRTC stack that runs Drop delivers live video to browsers worldwide. If you need that, start at live streaming.

Interactive live streaming

Zero-latency WebRTC live streaming for streamers, live commerce and events: real-time chat and votes over data channels, picture-in-picture, adaptive quality, recording and playback protection.

Learn more · Contact us