TL;DR
Stable Diffusion 3.5 Large is 15 GB. RealVisXL is 6.5 GB. Throw in a few LoRAs and a VAE, and your SSD hits the wall fast. I run a MinIO bucket as the long-tail model store, sync it to a local overflow directory on a 30-minute schedule via rclone, and register both the hot (SSD) and cold (synced overflow) paths in ComfyUI’s extra_model_paths.yaml. Models appear transparently; the loader searches both tiers. A fresh model lands in MinIO, appears locally within 30 minutes, and ComfyUI finds it without any manual shuffling.
The problem: model sprawl
I started with three checkpoints on the local SSD. That was fine for a 2 TB NVMe.
Six months later, I had:
- RealVisXL, SD 3.5 Large, Juggernaut XI (~28 GB)
- Five LoRAs (~4 GB)
- Custom VAEs (~2 GB)
- Checkpoints I wanted to keep just in case (~15 GB)
- Control-Net models (~3 GB)
Total: ~52 GB of model files on a drive that needs headroom for output images, temp files, and anything else the Mac Studio decides to cache. That was unsustainable. Every new model meant deleting an old one or buying more storage.
The honest solution is tiering: hot models on the SSD (the ones I actually use), everything else in object storage (S3 or MinIO), with a simple sync job mirroring the cold storage to a local overflow directory on-demand. ComfyUI’s extra_model_paths.yaml lets you register multiple model directories. The loader searches all of them. So the question becomes: how do I keep that sync fast enough that a fresh model is available within minutes, not hours?
MinIO as the model archive
I already run MinIO in the cluster as the S3-compatible object store for Longhorn backups and general-purpose storage. Adding a bucket for model artifacts is trivial — it’s just another bucket policy in the k3s namespace and a set of access credentials.
The bucket layout is flat:
comfy-assets/models/
├── checkpoints/
│ ├── RealVisXL_V5.0_fp16.safetensors
│ ├── sd3.5_large.safetensors
│ └── ... (others archived here)
├── loras/
├── vae/
└── controlnet/
I got the bucket endpoint (https://minio-s3.k3s.internal.zolty.systems), generated a pair of read-write access keys, and stored them in Ansible vault. The sync job will fetch them from there.
The rclone sync job
I used rclone because it’s battle-tested, bidirectional if I want it, and has smart filters and partial-file recovery. The launchd plist runs it on a 30-minute schedule:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.comfyui.minio-sync</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/rclone</string>
<string>sync</string>
<string>minio-homelab:comfy-assets/models</string>
<string>/Users/zolty/comfyui-nas-models</string>
<string>--no-check-certificate</string>
<string>--transfers</string>
<string>4</string>
<string>--log-level</string>
<string>INFO</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>1800</integer>
<key>StandardOutPath</key>
<string>/tmp/comfyui-model-mount.log</string>
<key>StandardErrorPath</key>
<string>/tmp/comfyui-model-mount.log</string>
</dict>
</plist>
Key details:
minio-homelabis the rclone remote name (configured in~/.config/rclone/rclone.confwith endpoint, access key, and secret key).- The local target is
~/comfyui-nas-models. It gets created if it doesn’t exist; rclone is idempotent. --no-check-certificateskips TLS verification — safe because MinIO is internal-only. (Use proper certs if exposed to the internet.)--transfers=4parallelizes the sync to four concurrent downloads, balancing throughput against network load.--log-level=INFOkeeps logs readable;DEBUGwould be spammy.StartInterval: 1800means 30 minutes. I chose that because: (a) it’s frequent enough that a new model is live within a window, (b) it’s infrequent enough that the network and SSD aren’t constantly thrashing, (c) if I add models manually, they appear within a reasonable time.
The launchd agent runs at login and continues on the schedule. Logs go to /tmp/comfyui-model-mount.log for troubleshooting.
The rclone config block looks like this:
[minio-homelab]
type = s3
provider = Minio
endpoint = https://minio-s3.k3s.internal.zolty.systems
access_key_id = <access_key>
secret_access_key = <secret_key>
Wiring it into ComfyUI
Once the sync is running, the final piece is registering the overflow directory with ComfyUI. The extra_model_paths.yaml file in the ComfyUI root tells the loader where to find models:
# ~/comfyui/extra_model_paths.yaml
# MinIO model overflow — rclone syncs comfy-assets/models to ~/comfyui-nas-models every 30 min
minio_overflow:
base_path: /Users/zolty/comfyui-nas-models
checkpoints: checkpoints/
loras: loras/
vae: vae/
controlnet: controlnet/
clip: clip/
That’s it. The minio_overflow entry tells ComfyUI to search ~/comfyui-nas-models/checkpoints/, ~/comfyui-nas-models/loras/, etc. alongside the default ~/comfyui/models/checkpoints/, ~/comfyui/models/loras/, etc.
When you open the model picker in ComfyUI (or hit the checkpoint loader node), it searches all registered paths. A model synced from MinIO appears in the dropdown immediately after the rclone job finishes. The user doesn’t know—or care—whether it came from the SSD or the overflow directory. Both look the same.
The hot/cold policy
I keep three models on the hot path (an NVMe SSD) because I reach for them daily:
RealVisXL_V5.0_fp16.safetensors(6.5 GB) — for photoreal headers and imagessd3.5_large.safetensors(15.3 GB) — for technical diagrams (most literal prompt-following)Juggernaut-XI-byRunDiffusion.safetensors(6.7 GB) — for cinematic/portrait mood
Everything else lives in MinIO. If I grab an older checkpoint or experiment with a new one, I upload it to MinIO, wait for the next sync window (max 30 min), and it’s available. No manual moving, no SSH. I can add models from anywhere — the MinIO web console, another machine running rclone, or a script.
For ComfyUI specifically, I also pre-download common LoRAs and VAEs. They’re small enough to keep hot, and the quality bump is worth the space. Control-Net models stay cold; I don’t use them enough.
Bandwidth and latency caveats
The sync job transfers everything that’s changed since the last run. For a 6 GB checkpoint, that’s a ~2-minute download on my gigabit link. First load from cold storage is slow. ComfyUI fetches the file into RAM before inference, so on the first run after a sync, there’s a 2-3 minute stall before the generation starts.
Subsequent runs use the cached copy. The SSD is fast; no re-download happens.
If you’re on a slower link or have bandwidth limits, increase StartInterval to 3600 (hourly) or tie the sync to a cron that runs at off-peak hours. I’ve considered a webhook that triggers rclone immediately when a file lands in MinIO, but 30 minutes is “good enough” for a homelab.
You still own the MinIO backups. This doesn’t replace real backups. The bucket is a convenience copy, not a disaster-recovery store. I run nightly snapshots to S3 (AWS) for the critical stuff; the model bucket is nice-to-have.
The honest caveats
- Sync lag. A fresh model added to MinIO doesn’t instantly appear locally. The next 30-minute sync window picks it up. If you need immediate access, either bump the interval or run
rclone syncmanually. - First-load latency. A model pulled from cold storage cold-starts at full size (6+ GB download + load time). Subsequent use is instant (SSD-cached). Plan for that if you’re iterating fast.
- Bandwidth. Even at 4 parallel transfers, a full sync of a large bucket takes time. If you’re on a slow link or metered connection, watch the logs.
- No deduplication. If you have ten copies of the same model (different names), they each take space in MinIO and each sync separately. Be disciplined about naming and versioning.
Lessons
- Tiering is essential for a growing model library. SSD space is expensive and finite. Cold storage is cheap and infinite (relative to a homelab budget).
- rclone + launchd is a clean pattern on macOS. No server daemons, no container overhead, no SSH tunneling. A plist and a cron-like interval.
- Transparent path lookup beats manual management. ComfyUI’s multi-path model loading is the feature that makes this work. Users add a model to the bucket; it appears in the loader. Done.
- 30 minutes is a good default. Frequent enough to feel responsive, infrequent enough that network and storage aren’t hammered. Adjust based on your tolerance for lag.
- MinIO + rclone is portable. This pattern works identically against AWS S3, Backblaze B2, or any S3-compatible object store. If you move clusters or migrate to the cloud, your model sync job is unchanged.
Related
- https://blog.zolty.systems/posts/2026-04-11-comfyui-mac-studio-mps/ covers standing up ComfyUI on the Mac Studio behind k3s ingress.
- https://blog.zolty.systems/posts/2026-06-18-comfyui-blog-image-pipeline/ walks the MCP tool and the prompt-to-page generation workflow.
No homelab object store? A DigitalOcean Spaces bucket is S3-compatible and works identically — set the rclone remote to the Spaces endpoint and credentials, and the same sync job works on a VPS or Droplet. Model tiering doesn’t require on-prem infrastructure; it just needs object storage and a machine with rclone available.