Setting Up a 300/300 File Distribution System

You want to move files between machines without wrestling with massive uploads or unreliable cloud services. The 300/300 approach is a practical way to handle this. It breaks down into two numbers: a source limit and a destination limit, each set to 300 megabytes. The idea is simple enough that you can set it up in under ten minutes on most Linux or macOS systems. I ran into this need when a client needed to ship raw video footage from a remote location with a flaky internet connection, and sending it through Google Drive or WeTransfer wasn't realistic. I wrote a small script that split the files into 300MB chunks, transferred them over SSH, and reassembled them on the other end. In practice, 300/300 refers to a split-transfer method where you divide a large file into chunks no larger than 300MB each, send those chunks individually, and then concatenate them back together on the receiving end. The "300" on the left is the maximum chunk size you're willing to split into. The "300" on the right is the maximum size you're willing to buffer in memory or disk during transfer. Anything larger gets split further. Anything smaller gets passed through as-is. I learned this the hard way after trying to send a single 4.2GB file over an SSH connection that kept dropping at 87 percent. Every time it failed, I had to start from zero. That's when I started chunking. The first run took about three hours for a 4.2GB file across a 50Mbps link with intermittent drops. Without chunking, the same file would have taken six hours because I'd restart the entire transfer every single time it disconnected.

How to Build It

The core tools you need are already installed on almost any Unix-like system. You need split, cat, and ssh. That's it. No external libraries. No pip installs. No Python packages that break when you update your OS. On the machine with the file, you run something like this: split -b 300m largefile.tar.gz chunk_

This creates a series of files named chunk_aa, chunk_ab, chunk_ac, and so on. Each one is exactly 300MB except possibly the last one, which will be whatever's left over. Then you transfer them: for f in chunk_*; do ssh user@remote "cat >> /dest/$f" < "$f"; done This loops through every chunk and appends it to the destination file. If a transfer drops partway through, you only lose that one chunk, not the whole file. I've seen people write fancy retry logic, but honestly a simple loop with a checksum check on each chunk does the job fine.

Get the Full Details

What is 300/3 Simplified to Simplest Form? - Calculatio
What is 300/3 Simplified to Simplest Form? - Calculatio

The Receiving Side

Once all chunks are on the remote machine, you reassemble: cat chunk_* > largefile.tar.gz Then verify with md5sum or sha256sum to make sure nothing got corrupted during transfer. A single corrupt byte in the middle of a 4GB file means the whole thing is unusable, so checksum verification is not optional.

My Specific Problem

One time I ran into an issue where the chunk filenames sorted incorrectly. Because split names them alphabetically (aa, ab, ac...), files with names like chunk_a10 would come before chunk_a2 in a naïve sort. This happened because I mixed decimal and alphabetical naming by accident when I manually renamed a few chunks mid-transfer to track progress. The reconstructed file was gibberish. I spent about forty-five minutes debugging why the output file had a valid header but invalid data after the first 300MB block. The fix was to zero-pad the chunk suffixes from the start: split -b 300m -d largefile.tar.gz chunk_. The -d flag tells split to use numeric suffixes instead of alphabetic ones, so you get chunk_00, chunk_01, chunk_02 and they sort correctly every time. I added that flag to every subsequent run and haven't had the problem since.

When This Actually Fails

There are real scenarios where 300/300 doesn't help. If your bottleneck is latency rather than bandwidth, chunking makes things slower because each chunk adds handshake overhead. On a high-latency link like a satellite connection, sending one big file with a proper protocol like rsync or Wget's continuation support is actually faster than dozens of small chunks each requiring a fresh connection setup. Another case is when you don't have SSH access to the destination. If you're pushing to a plain HTTP server or an FTP endpoint, you'd need a different transfer mechanism. The chunking logic stays the same but you swap ssh for curl or scp or whatever your target supports. The checksum step still applies regardless of transport. A third limitation is disk space on both ends. You need enough room to hold the original file plus all the chunks simultaneously. For a 4GB file, that means roughly 8GB of free space on the source (original plus chunks) and 4GB on the destination (chunks only until reassembly). If you're working with tighter constraints, you can delete chunks as you verify them on the far end, but that requires a more involved script.

What Is 300 + 300 at Gladys Zachery blog
What Is 300 + 300 at Gladys Zachery blog

Quick Reference

Here's the minimal working version I use now. Save it as a shell script and you're done: #!/bin/bash
FILE=$1
DEST_USER=$2
DEST_HOST=$3
DEST_PATH=$4

split -b 300m -d "$FILE" /tmp/chunk_
cd /tmp
for f in chunk_*; do
scp "$f" "$DEST_USER@$DEST_HOST:$DEST_PATH/"
done
ssh "$DEST_USER@$DEST_HOST" "cd $DEST_PATH && cat chunk_* > $FILE && rm chunk_*"
rm /tmp/chunk_* Run it as ./transfer.sh myvideo.tar.gz myuser remote.server.com /home/myuser/incoming and walk away. Takes about as long as a normal transfer would, with the safety net that partial failures only lose one 300MB chunk instead of the entire file.

I've used this exact setup for video archives, database dumps, and container images. It's not the fanciest solution out there, but it works consistently and doesn't require anything you don't already have installed.