case studies

BitSpeed Transfer Case Study Resumes a Killed 256 MiB Upload

The test is blunt. Start a file transfer, kill both ends with SIGKILL partway through, start them again and see what happens. No clean shutdown, no chance to save state on the way out. If the tool’s bookkeeping is honest, the restart should know exactly which pieces arrived and send only the rest.

This run used the released Linux amd64 build of Transfer 0.1.0, downloaded from the release and checked against its SHA256SUMS. The file was 256 MiB of random data called video.mov, split into 256 chunks of 1 MiB. Sender and receiver ran on the same machine over loopback.

Prepare, send, SIGKILL both processes, restart, status shows 136 verified and 120 missing, send again, digest matches.

Prepare, then delete the original

./bitspeed-transfer send --prepare-only --source=video.mov --spool=sender --chunk-size=1048576

Preparation copies the file into a local snapshot, hashes every chunk and the whole file, and returns a manifest. The transfer ID came back as 744b1dbc…ff5500458. The original video.mov was then deleted. From here on, Transfer works only from its own snapshot, so a source that changes or disappears can’t corrupt a resume.

Send and kill

With the receiver running, the send started:

./bitspeed-transfer serve --root=receiver --token-file=token --listen=127.0.0.1:8090
./bitspeed-transfer send --spool=sender --reuse=TRANSFER_ID --url=http://127.0.0.1:8090 --token-file=token

A second and a half in, both processes were killed with kill -9. At that moment the receiver had 136 chunk files on disk.

Restart and ask

The receiver came back on the same root and token. Before sending anything, the status command asked what it could prove:

./bitspeed-transfer status --url=http://127.0.0.1:8090 --id=TRANSFER_ID --token-file=token

The answer: state uploading, 136 verified chunks, 142,606,336 verified bytes, and a missing list running from chunk index 136 to 255, which is 120 chunks. The receiver didn’t trust a progress counter. It rechecked the stored chunks against their hashes on restart and reported only what passed.

Resume

The same send command, same spool, same ID. It finished in about five seconds and printed transferred true with a receipt. The receipt names the output file and its SHA-256, 651b3dcd…b883683. That’s the same digest the original file had before it was deleted. The receiver published one file under receiver/files, and the sender saved the receipt locally before reporting success.

What to take from it

Interrupting a Transfer run costs you the chunks that were in flight, nothing more. The restart re-verifies what it has instead of trusting what it wrote down, and completion means a checked digest and a saved receipt, not just the last byte sent.

Two honest costs showed up too. The sender’s snapshot is a full extra copy, 257 MB here. The receiver held 513 MB at the end, because stored chunks stay until you clean them up following the retention procedure. Transfer 0.1.0 delivers on Linux and macOS only. The quick start has the full command sequence and the download page lists what each archive was tested on.