← All guides

How to Move the Hugging Face Cache to Another Drive

Every model you pull with transformers, diffusers, vLLM or the hf CLI lands in ~/.cache/huggingface on your boot drive. One environment variable, HF_HOME, moves it. The hard part is moving the files you already have: the cache stores model files as symlinks into a blobs folder, and two common copy commands break that layout without printing an error.

Bottom Line

  • Set HF_HOME to a folder on the big drive. Set it before Python imports huggingface_hub. The variable is read at import time.
  • Or set HF_HUB_CACHE if you only want model downloads moved. It defaults to $HF_HOME/hub.
  • Copy with rsync -a or cp -R. Model files are relative symlinks into blobs/. Tools that follow or skip symlinks break the cache.
  • What we tested tonight: rsync -r dropped every model file with no error exit you would notice. Python shutil.copytree defaults tripled a two-revision cache.
  • Verify with hf cache ls and hf cache verify. Then delete the old folder.
  • TRANSFORMERS_CACHE is old advice. The current transformers guide lists HF_HUB_CACHE, HF_HOME and XDG_CACHE_HOME only.

Which Variable Moves What

The huggingface_hub environment variable reference defines one root and several children.

VariableDefaultWhat lives there
HF_HOME~/.cache/huggingfaceEverything below, plus your token
HF_HUB_CACHE$HF_HOME/hubModel, dataset and Space downloads. This is the big one.
HF_XET_CACHE$HF_HOME/xetXet chunk and shard caches
HF_ASSETS_CACHE$HF_HOME/assetsFiles that downstream libraries cache
HF_TOKEN_PATH$HF_HOME/tokenYour access token
XDG_CACHE_HOMEunsetUsed only when HF_HOME is not set

Pick HF_HOME in most cases. One variable moves every cache, and the Xet cache stops filling the boot drive too. Pick HF_HUB_CACHE when a policy keeps tokens on the system disk.

Deprecated names still work but lose to their replacements: HUGGINGFACE_HUB_CACHE is replaced by HF_HUB_CACHE, and HUGGING_FACE_HUB_TOKEN by HF_TOKEN. The transformers install guide no longer mentions TRANSFORMERS_CACHE at all.

Why a Normal Copy Can Break It

The hub cache is not a plain folder of model files. The cache guide documents this layout:

hub/
└── models--org--name/
    ├── blobs/        # real file data, named by hash
    ├── refs/         # branch name -> commit hash
    ├── snapshots/
    │   └── <commit>/
    │       └── model.safetensors -> ../../blobs/<hash>
    └── trees/        # cached file lists per commit

Each file in snapshots/ is a relative symlink to a blob. Two revisions that share a file point at the same blob, so the data is stored once. A copy tool has three options for each symlink: copy the link, copy the file it points at, or skip it. Only the first option gives you a working cache of the same size.

We Tested Five Copy Methods

We built a fake cache with one 50MB blob and two snapshot folders that link to it. That is the shape you get after a model repo updates and you download it again. Then we copied it five ways on macOS 26.3.

MethodSize after copySymlinks after copyResult
Original48MB2
cp -R src dst48MB2Works
rsync -a src/ dst/48MB2Works
shutil.copytree(src, dst, symlinks=True)48MB2Works
rsync -r src/ dst/48MB0Broken. Printed skipping non-regular file per link. Snapshots are empty.
shutil.copytree(src, dst)143MB0Bloated. Each link became a full copy.

The rsync -r failure is the dangerous one. The size looks right because the blobs copied. The model still fails to load, because the files the library opens were never created. With HF_HUB_OFFLINE=1 you get a missing-file error. Without it, the library simply downloads the model again into the new cache.

The copytree failure scales with your history. Our test cache had two revisions of one file. A cache that holds three revisions of a 17GB model can grow to 51GB on the new drive. Check any “move my cache” Python snippet for symlinks=True before you run it.

Both failures are general symlink behaviour, not a Hugging Face bug. The cache format just exposes them.

The Move, Step by Step

macOS and Linux

# 1. Copy, keeping symlinks as symlinks
rsync -a ~/.cache/huggingface/ /Volumes/BigDrive/huggingface/

# 2. Point the libraries at the new location (add to ~/.zshrc or ~/.bashrc)
export HF_HOME=/Volumes/BigDrive/huggingface

# 3. Open a new shell, then check the copy
hf cache ls
hf cache verify <org/model>

# 4. Only now remove the old cache
rm -rf ~/.cache/huggingface

Check the link count before you delete anything:

find ~/.cache/huggingface/hub -type l | wc -l
find /Volumes/BigDrive/huggingface/hub -type l | wc -l

The two numbers must match. A zero on the new drive means the copy tool dropped the links.

Services do not read your shell profile. A vLLM or text-generation server started by systemd needs Environment="HF_HOME=/mnt/bigdrive/huggingface" in its unit file. A shell export never reaches it. This is the same trap as moving Ollama models.

Docker containers need the mount and the variable. Mount the new folder into the container and set HF_HOME to the path inside the container.

Windows

  1. Copy C:\Users\<you>\.cache\huggingface to the new drive, for example D:\huggingface.
  2. Open Edit environment variables for your account and create HF_HOME with value D:\huggingface.
  3. Close every terminal and IDE, then reopen them.
  4. Run hf cache ls to check.

Windows often has no symlinks in the cache to begin with. The cache guide says huggingface_hub cannot create them without Developer Mode or admin rights. In that case it stores full files in snapshots/ and copies are simple. If you enabled Developer Mode, copy with a tool that keeps symlinks.

Shared Drives and External Disks

SituationSettingTradeoff
NAS shared by Linux and Windows machinesHF_HUB_DISABLE_SYMLINKS=1No deduplication. Each revision stores full files.
External USB driveHF_HOME on the driveIf the drive is not mounted, the library downloads again to the path.
Offline machineHF_HUB_OFFLINE=1Missing files raise an error instead of a silent re-download.

The docs recommend HF_HUB_DISABLE_SYMLINKS=1 for the NAS case, because symlinks created on Linux are not always traversable on Windows.

Set HF_HUB_OFFLINE=1 for the first run after a move. A broken copy then fails loudly. Without it, a broken copy costs you a full re-download and you may not notice.

Clean Up Before You Move

Moving garbage is slow. Two commands shrink the cache first:

hf cache ls --revisions --filter "size>1GB"   # find the big ones
hf cache prune                                  # delete unreferenced revisions and .incomplete files

hf cache prune removes revisions that no branch or tag points to, plus partial downloads. Old revisions are exactly the files that blow up a dereferencing copy, so pruning first also protects you from the copytree problem.

When It Does Not Work

SymptomCauseFix
Model downloads again after the moveVariable not set in that processSet HF_HOME before import; restart the kernel or service
hf cache ls shows repos but loading fails offlineCopy tool skipped symlinks (rsync -r)Re-copy with rsync -a
New drive is 2-3x larger than the old cacheCopy tool followed symlinksRe-copy with rsync -a, or run hf cache prune
Works in terminal, not in the serversystemd or Docker never saw the variableSet it in the unit file or container env
Token “lost” after the moveYou set HF_HOME, token lives in $HF_HOME/tokenCopy the token file too, or run hf auth login again

Do You Need a Bigger Drive Instead?

Moving the cache only helps if the target drive is large. Our model storage sizing guide has the numbers: 1TB fills fast, 2TB suits a single-GPU box, and 4TB suits a 48GB-VRAM machine. The cache grows fastest when you keep several quantizations of the same model.

See Also

Sources

  • huggingface_hub environment variablesHF_HOME, HF_HUB_CACHE, HF_XET_CACHE, HF_ASSETS_CACHE, HF_TOKEN_PATH, HF_HUB_DISABLE_SYMLINKS, HF_HUB_OFFLINE, deprecated names; read 2026-09-14
  • huggingface_hub cache guide — blobs/refs/snapshots/trees layout, relative symlinks, Windows limitation, hf cache ls, verify, prune; read 2026-09-14
  • transformers installation guide — cache variable priority list; read 2026-09-14
  • Copy-method test: run by us on macOS 26.3 (openrsync, Python 3) on 2026-09-14 with a synthetic cache of one 50MB blob and two snapshot symlinks. GNU rsync and GNU cp were not tested.

Need OpenClaw fixed live?

Remote rescue sessions for gateway, auth, tunnel, VPS, and model access problems.

See Rescue Session

Read next

How to Move Ollama Models to Another Drive (macOS, Linux, Windows)
Set OLLAMA_MODELS and move your model library off a full boot drive. The official steps per operating system, the systemd drop-in written out, and the macOS gotcha the docs do not mention: launchctl setenv does not survive a reboot.
The Ollama Models You Cannot Find by Searching Ollama
I made a video about this because most people running Ollama never realize it. Search Ollama's catalog and you see a curated list, but the much larger set of models lives on Hugging Face, and you do not need any of them to be on the official list to run them. Here is the one comm
NVIDIA PAIR (2026): It Does Not Pool Your GPU Memory
NVIDIA PAIR routes whole inference requests to whichever PC on your LAN has capacity. NVIDIA's own FAQ says it does not combine devices into one virtual GPU, so a second box will not let you run a model that does not already fit on one machine.
How Much VRAM for 128K Context? The Exact Math
Qwen3 32B needs exactly 32GB of KV cache at 128K context — more than the weights. The formula, worked from real config.json files, plus the detail nobody mentions: Qwen3's native context is 40,960 tokens, not 128K.