The honest answer is to script it: keep a model list next to your workflows and run one download script the moment a new instance is up. QuantaCloud instances start clean, and stopping one deletes the instance and its disk, models included, with no volumes or snapshots to keep them. So the download is part of every session, and the script decides whether it takes one command or twenty. The one below reads a list of folders and URLs, fetches Hugging Face files with the hf CLI and Civitai files with curl and your token, and puts each file in the ComfyUI folder its loader reads.
Where each file goes in the models folder#
The rule I follow is that the loader node decides the folder, not the file name. ComfyUI v0.37.0 reads these folders under models:
| Folder | What goes there | Node that loads it |
|---|---|---|
checkpoints | All-in-one files: model, text encoder and VAE together | Load Checkpoint |
diffusion_models | Diffusion model weights on their own. The older name unet still works | Load Diffusion Model |
text_encoders | CLIP, T5, umT5, Qwen and other text encoders. The older name clip still works | Load CLIP, Load CLIP (Dual) |
vae | VAE files | Load VAE |
loras | LoRA files | Load LoRA, Load LoRA (Model and CLIP) |
clip_vision | Image encoders for image prompts | Load CLIP Vision |
controlnet | ControlNet and T2I-Adapter models | Load ControlNet Model |
upscale_models | Upscalers such as ESRGAN models | Load Upscale Model |
embeddings | Textual inversion embeddings | Named in the prompt as embedding:name |
Where models itself sits depends on how ComfyUI got onto the machine. comfy-cli installs it in ~/comfy/ComfyUI/models, a manual clone in ~/ComfyUI/models, and the image from running ComfyUI in Docker mounts ~/comfy-docker/data/models. On QuantaCloud's ComfyUI template, ComfyUI runs in a container, and the running server tells you the path, as shown further down. Press r in ComfyUI after a download so the loaders list the new files.
A typical set and how big it is#
The example set covers images and video: SDXL, FLUX.1 [schnell] and Wan 2.2's 5B video model with the text encoder and VAE it needs. The sizes are the byte counts on Hugging Face.
| File | Folder | Size | License |
|---|---|---|---|
sd_xl_base_1.0.safetensors | checkpoints | 6.94 GB | CreativeML Open RAIL++-M |
flux1-schnell-fp8.safetensors | checkpoints | 17.24 GB | Apache-2.0 |
wan2.2_ti2v_5B_fp16.safetensors | diffusion_models | 10.00 GB | Apache-2.0 |
umt5_xxl_fp8_e4m3fn_scaled.safetensors | text_encoders | 6.74 GB | Apache-2.0 |
wan2.2_vae.safetensors | vae | 1.41 GB | Apache-2.0 |
Together that is 42.32 GB (our calculation from the byte counts). The disk that comes with each configuration is fixed: in the 2026-09-27 catalog it ranged from 256 GB on an RTX A6000 1x to 1,250 GB on an H100 PCIe 1x, and the GPU pages list the live configurations.
Check the free space before the first download:
df -h
The model list#
The list is a plain text file with one file per line: the folder, the URL, and for anything that is not on Hugging Face, the name to save it under. I pin Hugging Face URLs to a commit instead of main, so every launch gets the same bytes. The commit is in the repository's history on huggingface.co. Save this as models.txt:
# folder URL [file name]
checkpoints https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/462165984030d82259a11f4367a4eed129e94a7b/sd_xl_base_1.0.safetensors
checkpoints https://huggingface.co/Comfy-Org/flux1-schnell/resolve/c2b683ea00713d6feadcd54b39e3725bbc78638b/flux1-schnell-fp8.safetensors
diffusion_models https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/ee6f4a40737a995bf5818954cfce6d59443b0f04/split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors
text_encoders https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/ee6f4a40737a995bf5818954cfce6d59443b0f04/split_files/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors
vae https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/ee6f4a40737a995bf5818954cfce6d59443b0f04/split_files/vae/wan2.2_vae.safetensors
# A Civitai file: the version ID from the model page's download link, then the file name
# loras https://civitai.com/api/download/models/<version-id> <file-name>.safetensors
For a Civitai model, the number in the download link is the model version ID. The third column is the name to save the file under, usually the file name shown on the model page, because that is the name your workflows expect.
The download script#
The script is the part you write once. It reads the list, skips files that are already in place, downloads Hugging Face files with hf download and everything else with curl, and moves each file into its folder. Save it as get-models.sh:
#!/usr/bin/env bash
# get-models.sh: download every file in a model list into ComfyUI's models folder.
# Usage: MODELS=/path/to/ComfyUI/models bash get-models.sh models.txt
set -euo pipefail
MODELS="${MODELS:-$HOME/comfy/ComfyUI/models}"
STAGE="$MODELS/.staging"
CIVITAI_TOKEN="${CIVITAI_TOKEN:-$(cat "$HOME/.config/civitai-token" 2>/dev/null || true)}"
while read -r folder url name || [ -n "${folder:-}" ]; do
case "$folder" in ""|\#*) continue ;; esac
path=""
if [[ "$url" == https://huggingface.co/*/resolve/* ]]; then
url="${url%%\?*}"
rest="${url#https://huggingface.co/}"
repo="${rest%%/resolve/*}"
rev="${rest#*/resolve/}"; path="${rev#*/}"; rev="${rev%%/*}"
name="${name:-${path##*/}}"
fi
if [ -z "${name:-}" ]; then echo "add a file name after $url" >&2; exit 1; fi
dest="$MODELS/$folder/$name"
if [ -s "$dest" ]; then echo "have $folder/$name"; continue; fi
mkdir -p "$MODELS/$folder"
echo "get $folder/$name"
if [ -n "$path" ]; then
hf download "$repo" "$path" --revision "$rev" --local-dir "$STAGE"
mv "$STAGE/$path" "$dest"
else
if [[ "$url" == https://civitai.com/* && -n "$CIVITAI_TOKEN" ]]; then
if [[ "$url" == *\?* ]]; then url="$url&token=$CIVITAI_TOKEN"; else url="$url?token=$CIVITAI_TOKEN"; fi
fi
curl -fL --retry 3 -o "$dest.part" "$url" \
|| { echo "failed: $folder/$name (check the URL and your token)" >&2; exit 1; }
mv "$dest.part" "$dest"
fi
done < "${1:-models.txt}"
rm -rf "$STAGE"
Three details carry it. hf download with --local-dir keeps the repository's folder structure, so a Comfy-Org file under split_files/vae/ lands in the staging folder first and then moves into vae. The staging folder sits inside models on the same disk, which makes the move instant. And the Civitai token goes into the URL the way Civitai's own guide shows, while curl prints only its progress meter and, on a failed request, an HTTP error code, so the URL, token included, never reaches your terminal or a log.
Tokens for gated and login-only files#
The one thing I do before launching is get the tokens ready, because a gated file stops the script halfway. Hugging Face repositories such as Black Forest Labs' FLUX.1 [dev] need you to accept the license on the model page and a read token from your account settings. Civitai creators can require a login for downloads, and Civitai issues API tokens under your account settings at civitai.com/user/account.
Save each token in a file on your own machine first, ~/.config/hf-token and ~/.config/civitai-token, with a text editor rather than echo, and chmod 600 both. Then put them on the instance, reading them from those files so they never appear on a command line or in your shell history:
ssh ubuntu@<instance-ip> 'mkdir -p ~/.cache/huggingface ~/.config && umask 077 && cat > ~/.cache/huggingface/token' < ~/.config/hf-token
ssh ubuntu@<instance-ip> 'umask 077 && cat > ~/.config/civitai-token' < ~/.config/civitai-token
hf reads its token from ~/.cache/huggingface/token by default, and the script reads the Civitai token from ~/.config/civitai-token unless CIVITAI_TOKEN is set. Downloading Hugging Face models fast covers gated access and the hf CLI in more depth.
Run it on each launch#
The routine is the same on every launch: copy the two files over, install hf, and run the script inside tmux so a dropped SSH connection cannot stop it.
On your own install
With ComfyUI installed by comfy-cli on the Bare Metal template, the default target is already right. The ComfyUI guide covers that install.
- Copy the list and the script from your own machine:
scp models.txt get-models.sh ubuntu@<instance-ip>: - On the instance, install
hfwith uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
uv tool install hf
- Run the script in tmux:
tmux new -s models 'bash get-models.sh models.txt; bash'
For your own Docker image, set the target first: MODELS=~/comfy-docker/data/models bash get-models.sh models.txt.
On the ComfyUI template
On the ComfyUI template, ComfyUI runs in a Docker container and reads its models from a folder inside that container. Download on the VM first, then copy the files in with docker cp, so nothing has to be installed inside the container and your tokens stay on the VM. Install hf as above, start tmux new -s models, and run this inside it:
C=$(sudo docker ps -q --filter publish=8188)
IN=$(curl -s http://127.0.0.1:8188/internal/folder_paths | python3 -c 'import json, os, sys; print(os.path.dirname(json.load(sys.stdin)["checkpoints"][0]))')
echo "$IN"
MODELS=~/models-staging bash get-models.sh models.txt
sudo docker cp ~/models-staging/. "$C:$IN/"
rm -rf ~/models-staging
The second line asks the running ComfyUI where its model folders are. That /internal route exists for ComfyUI's own frontend and may change between releases, so check the path it prints before you copy. A source path ending in /. makes docker cp copy the folder's content, so checkpoints, vae and the rest land inside the container's models folder.
While both copies exist, the set takes twice its size on disk: 84.64 GB of an RTX A6000's 256 GB for the example (our calculation: 2 x 42.32 GB), so delete the staging folder as soon as the copy finishes. ComfyUI-Manager's model installer is not a shortcut here: at its default security level it blocks model installs whenever ComfyUI listens beyond localhost, which a ComfyUI inside a container usually does.
What the downloads cost#
Download time is GPU time: billing runs from launch to stop, whatever the instance is doing. At the lowest RTX A6000 price on 2026-09-27, $0.48 per hour, ten minutes of downloading costs $0.08 (our calculation: 10/60 x $0.48). The lowest RTX A6000 price right now is $0.48/GPU-hr. When you stop, the unused seconds of the current hour are refunded, so the cost of a session is the time it ran. Pricing has the full billing rules.
Two habits keep that time short. Download only the files your workflows load, because Hugging Face repositories often hold the same model in several precisions. And start the script before you do anything else, so the files arrive while you set up the rest.
Frequently asked questions#
Where is the ComfyUI models folder?
Inside the ComfyUI folder: ~/comfy/ComfyUI/models for a comfy-cli install and ComfyUI/models for a manual clone. On the QuantaCloud ComfyUI template it is inside the container, and /internal/folder_paths on the running server prints it.
Can I keep models between sessions on QuantaCloud?
No. Stopping an instance terminates it and deletes its disk, and there are no volumes or snapshots. The model list and the script are what you keep, in Git or on your own machine.
Why not upload models from my own computer?
You can, with rsync or scp, but every launch would push the whole set through your own upload connection again. Upload only the files that exist nowhere else, such as a LoRA you trained, and moving files to and from a GPU server covers the commands.
How do I add a model from Civitai?
Add a line with the folder, the model's download link and the file name, set up your Civitai token, and run the script again. It skips the files already in place and fetches only the new one.
My rule for models on a fresh instance: the model list is part of the project, pinned to commits, and the script runs before anything else on every launch. Copy your outputs off before you stop, because the disk goes with the instance. From here, ComfyUI GPU requirements helps you size the card for a set, and the ComfyUI page launches the template.
Launch ComfyUI on an RTX A6000