Plot one Chia k32 at a time on a plotter, then fully move that plot to a remote harvester before starting the next one. Repeat until every configured destination drive is full.
chia-fill is a small bash wrapper around madMAx chia_plot and rsync. It is meant for a two-machine setup: fast temp disks on the plotter, final .plot files on the harvester.
chia_plot -d is local staging, not the harvester. The real destination is another machine (user@host:/mnt/hdd-NN).
A k32 plot is about 102 GiB. If you start the next plot before the previous file has finished transferring, staging fills up, temp disks get crowded, and a failed copy is easy to miss. chia-fill makes the contract explicit:
- Create one plot into local staging.
rsyncit to the harvester.- Confirm the remote file exists at the same size.
- Remove the local copy.
- Only then start the next plot.
If the move fails, the loop stops immediately and prints a red JOB FAILED banner. It will not keep plotting on top of a stuck transfer.
plotter machine harvester
--------------- ---------
chia_plot -t / -2 (tmp SSD)
|
v
chia_plot -d local staging .plot
|
| rsync --whole-file (as *.xfer, then rename to .plot)
v
user@host:/mnt/hdd-01, /mnt/hdd-02, ...
On the plotter:
- bash,
ssh,rsync,flock(util-linux) - madMAx
chia_plot - SSH key login to the harvester (no password prompt;
BatchModeis required) - Enough staging disk for at least one finished k32 (~102 GiB)
On the harvester:
- SSH server
- The destination mount points already exist (for example
/mnt/hdd-01)
git clone https://github.com/<you>/chia-fill.git
cd chia-fill
chmod +x chia-fill.sh
cp chia-fill.conf chia-fill.conf.local # optional: keep a private copyEdit chia-fill.conf (or pass flags) so the plotter path, temp disks, pool contract, farmer public key, and remote drives match your machines.
# See what the script will use
./chia-fill.sh --show-config
# One plot, then one move, then exit
./chia-fill.sh --once
# Fill every destination that still has at least 102 GiB free
./chia-fill.shConfirm SSH works first:
ssh steve@jango 'df -h /mnt/hdd-01'Defaults live in chia-fill.conf next to the script. CLI flags override the config.
| Setting | Meaning |
|---|---|
PLOTTER |
Path to the chia_plot binary |
TMP_DIR |
chia_plot -t working temp |
TMP2_DIR |
chia_plot -2 second temp |
STAGING_DIR |
chia_plot -d — local directory where the finished .plot lands |
POOL_CONTRACT |
Pool contract address (-c) |
FARMER_KEY |
Farmer public key (-f) |
THREADS |
Plotter thread count (-r) |
PLOT_LOG |
Tee'd plotter output |
DEST_USER / DEST_HOST |
Harvester SSH target |
DEST_PATHS |
Remote drives, in preference order |
BWLIMIT |
rsync --bwlimit (for example 800m) |
MIN_FREE_GB |
Do not start a plot unless a dest has at least this much free (default 102) |
PLOTTER_RETRIES |
Plotter failures to retry before aborting |
LOCK_FILE |
Prevents two chia-fill runs on the same plotter |
FILL_LOG |
Optional extra copy of chia-fill log lines |
PLOT_COUNT is forced to 1 at runtime. Sequential fill only works if each cycle produces a single plot.
Do not commit a config that contains machine-specific paths you want private. The sample chia-fill.conf in this repo is a template (YOUR-POOL-CONTRACT-ADDRESS, YOUR-FARMER-KEY).
-c, --config FILE Config file (default: ./chia-fill.conf)
--plotter PATH chia_plot binary
-t, --tmp PATH chia_plot -t temp directory
-2, --tmp2 PATH chia_plot -2 second temp directory
-d, --staging PATH Local staging directory (chia_plot -d)
-u, --user USER Remote user
-H, --host HOST Remote host
-p, --path PATH Remote destination path (repeatable; replaces the config list)
-b, --bwlimit LIMIT rsync bandwidth limit (e.g. 800m)
-r, --threads N Plotter thread count
-m, --min-free-gb N Minimum free GiB required on a destination
-n, --max-plots N Stop after N successful plot+move cycles (0 = until full)
--once Same as --max-plots 1
--drain-only Move leftover staging plots; do not create new ones
--dry-run Print actions without plotting or transferring
--show-config Print effective settings and exit
-l, --log FILE Also append chia-fill messages to this file
-h, --help Show help
Examples:
# Override host and a couple of drives for this run
./chia-fill.sh -H jango -p /mnt/hdd-05 -p /mnt/hdd-06 --bwlimit 400m
# Move whatever is already sitting in staging, then stop
./chia-fill.sh --drain-only
# Simulate one cycle (SSH is still used to inspect free space)
./chia-fill.sh --dry-runFor each finished .plot in staging, chia-fill:
- Picks the first remote path in
DEST_PATHSthat exists and has at leastMIN_FREE_GBfree. rsync --whole-filetofilename.plot.xferon the harvester (so a harvester scanning*.plotwill not pick up a partial file).- Renames
.xfer→.ploton the remote side. - Compares local and remote sizes.
- Deletes the local file only after that check succeeds.
If a same-size copy is already on the remote, the local file is removed and the move is treated as done. Leftover plots in staging from a crash are drained before the next plot starts.
SSH connections use a ControlMaster socket so the many df / stat checks do not open a new TCP session every time.
| Situation | Result |
|---|---|
Every reachable dest is below MIN_FREE_GB |
Success — “all destinations are full” |
| rsync, remote rename, or size check fails | Job failed — red banner, exit 1, local plot kept |
Plotter exits 0 but no .plot appears in staging |
Job failed |
Plotter fails more than PLOTTER_RETRIES times |
Job failed |
| SSH to the harvester fails | Job failed |
--max-plots / --once reached |
Success |
--drain-only finished |
Success |
A failed move leaves the local .plot in staging so you can fix the harvester and re-run ./chia-fill.sh --drain-only.
Only one chia-fill process can run at a time (LOCK_FILE + flock).
- Run it in
tmuxorscreen. A k32 plus a 102 GiB rsync takes a while. --bwlimitkeeps the LAN usable while plots copy.800mis 800 Mbit/s in rsync units, not megabytes.MIN_FREE_GBshould stay at or above one k32 (102) so a drive is never chosen when the plot cannot fit.- Destination order in
DEST_PATHSis the fill order. Put the drive you want filled first at the top of the list. - The farmer key in
chia_plot -fis the public farmer key fromchia keys show, not a private mnemonic.
Use and modify freely. No warranty: plots are large and slow to rebuild, so test with --show-config, --dry-run, and --once before an unattended fill.