AI SeedbankHelp preserve open and free AI for humanity's future

Ollama pull slow or stuck? What actually fixes it

Last updated: 2026-09-01

An ollama pull runs slow for reasons you can read in the client's own source, and none of them is a missing speed variable. The client fetches a small manifest, asks the registry for a signed direct URL for each blob, splits that blob into parts of 100 to 1000 MB with up to 16 downloading in parallel, restarts any part that stalls for 30 seconds, and checks every finished layer against the manifest's sha256 digest. Re-running the same pull resumes part by part. The trap that eats resumed pulls sits elsewhere: at startup the server deletes partial files older than one hour, unless OLLAMA_NOPRUNE is set.

About those variables: much of the advice that ranks for a slow pull has you export OLLAMA_ settings that do not exist in current ollama. No variable raises the 16-part count, lifts the 30 second timeouts, or throttles a GGUF blob pull. The list that is real lives in the client's own configuration source, and this page sticks to it.

Slow ollama pulls come in five shapes, each with a different cause: slow the whole way means 16 parts fighting over a throttled or lossy path; fast then crawling near the end means the small-blob tail; stuck at one percentage means a stalled part cycling through retries; a bar that jumps backwards means the client rolled back its counter on an error while keeping your bytes; a pull restarting from zero means the partials were pruned, or the failure happened before any blob landed.

The ranked fixes, most likely to help first:

  1. Re-run the same pull. ollama pull llama3.1:8b resumes every part from where it stopped on disk.
  2. Protect a partial before a restart. OLLAMA_NOPRUNE=1 on the server stops the startup prune from deleting it.
  3. Know the one stream variable. OLLAMA_MAX_TRANSFER_STREAMS affects safetensors engine pulls only, default 4.
  4. Fix the path. HTTPS_PROXY on the server process, never HTTP_PROXY; then DNS and a wired link.
  5. Pull a smaller tag. ollama pull llama3.1:8b instead of llama3.1:70b trades accuracy for far fewer bytes.
  6. Skip the registry. Download the weights yourself and import them with a Modelfile; the walkthrough is below.

Not sure which shape you have? Match it in the decision block.

Which problem do you have?

One table, symptom to fix; two rows hand off to sibling guides because the bottleneck is not the ollama client.

SymptomLikely causeDo this
Slow from the first megabyte, all the way through16 parallel parts sharing a throttled or lossy path to the CDN hostFixes 1, 4 and 5. If huggingface.co itself is the slow part, that is a different guide
Fast, then crawling somewhere past 90 percentThe small-blob tail: what is left is small blobs, each needing its own signed URL inside 30 secondsLet it finish if the bar still moves; fix 1 if it errors
Stuck at one percentage, no errorA stalled part waiting out the 30 second timeout and its retriesFix 1, then fix 4 for the path
The bar jumps backwardsThe client rolled back the bytes it counted for a part that errored; the data on disk is keptNothing is lost. Fix 1 resumes it
The pull starts over from zeroThe startup prune deleted partial files older than an hour, or the failure was at the manifest stageFix 2 before the next restart
An error with a colon in itA direct URL fetch timed out (context deadline exceeded), a layer failed its digest check (digest mismatch), or part retries ran out (max retries exceeded)Fix 1, then fix 4. digest mismatch re-downloads that layer on the next pull
huggingface.co refused the request, with 401, 403 or 429The Hub said no before speed matteredThe error codes guide decodes that side
The model downloaded fine but answers crawlGeneration speed: tokens per second, GPU offload, context lengthNot a download problem. ollama's FAQ on docs.ollama.com covers inference tuning

What ollama actually does during a pull

Every pull is two steps. The client first fetches the manifest, the small file listing the layers; if that fetch fails you see pull model manifest: followed by the underlying error, and no blob has started. Then it downloads each blob the manifest lists.

Before a blob starts, the client asks the registry for a direct, signed URL on a CDN host, on a 30 second budget; failures log failed to get direct URL; backing off and retrying. The blob then splits into parts of 100 MB to 1000 MB, up to 16 fetching at once. A stalled part trips a 30 second timeout, and an errored part is retried up to 6 times with a delay that doubles from 1 second to 32. None of those numbers is a setting. They are constants in the downloader source.

Two behaviors in that file decide what an interruption costs. Existing partial files, named <blob>-partial-N, are found on the next run and each part continues from its stored offset, so re-running a pull does not restart it. On a generic part error it rolls back the bytes it had counted, so the bar can jump backwards while the data stays on disk.

When the last layer lands, the server hashes the file and compares it to the sha256 digest in the manifest. A mismatch deletes the file and errors with digest mismatch, file must be downloaded again. The pull flow, the startup prune and that digest check live in the images source.

Every symptom above now has an address: the manifest step, the direct URL, the parts, the rollback, or the prune.

Why pulls slow down, stall or run backwards

Six mechanisms cover the reports; the last column is the fix number.

What you seeWhat is happeningFix
Speed far below what your line does elsewhere, the whole pull16 parts competing on a path that drops or throttles connections (issue 7109)1, 4, 5
Fast, then a crawl past 90 percentThe small-blob tail. One user's hf.co pull split into 19 parts of 1 GB, 10 of 100 MB and one of 479 bytes, and it died on the 479 byte blob after the big layers finished (issue 17484)1
Stuck at one percentage, no errorA part waiting out the 30 second stall timeout and its retries, or a direct URL that cannot resolve inside its own 30 seconds1, then 4
Good speed, then TLS or connection errors naming a storage hostRouting or DNS to the CDN host, which varies by pull. Real logs name cdn-lfs hosts and Cloudflare R2 (issue 10050, issue 14868)4
The bar jumps backwardsThe client rolled back its counter on a part error; the bytes on disk are keptNothing. 1 resumes
Parts finish but the pull never completes, or a restart loses everythingA slow or full disk, or the startup prune deleting partial files older than an hourFree space, then 2

The fixes that exist, ranked

1. Re-run the same pull

The highest-value fact on this page: interrupting a pull does not throw it away. The client finds the -partial-N files from the earlier run and continues each part from its stored offset; finished layers are not touched again. Run the same command:

ollama pull llama3.1:8b

Use the same model and tag both times. What this cannot do: recover partials the prune already deleted, or speed up the path.

2. Set OLLAMA_NOPRUNE before the server restarts

If you have to stop mid-pull, the partials survive the stop itself. What they may not survive is the next start: the server deletes leftover partial files older than one hour at startup. Set the variable on the server process before that restart:

OLLAMA_NOPRUNE=1 ollama serve

On a Linux service install, add it to the service environment instead, with systemctl edit ollama.service and an Environment= line; the FAQ at docs.ollama.com documents environment setup per operating system. What this cannot do: bring back what the prune already removed.

3. OLLAMA_MAX_TRANSFER_STREAMS, and the variables that do not exist

One more download-related variable exists beyond the prune switch. OLLAMA_MAX_TRANSFER_STREAMS sets the parallel stream count for models pulled through the newer safetensors engine path, default 4:

OLLAMA_MAX_TRANSFER_STREAMS=8 ollama serve

Its scope is narrower than forum posts imply: classic GGUF blob pulls do not use it, and it helps only on the safetensors engine path.

Variables that are fiction: no OLLAMA_ variable raises the part count or lifts the timeouts. OLLAMA_NUM_PARALLEL and OLLAMA_MAX_LOADED_MODELS are inference concurrency, not download. At least one ranking guide recommends OLLAMA_GPU_MEMORY, which does not appear in current ollama's configuration source at all. The list that is real is envconfig/config.go.

4. Fix the path, not the client

When the errors name storage hosts, or everything else on your machine is fast, the client is the wrong end to work on. Three checks, in order of payoff.

Proxy first, and only ever the HTTPS form. ollama pulls over HTTPS, and its FAQ says to avoid HTTP_PROXY and set HTTPS_PROXY on the daemon, not just in your shell:

HTTPS_PROXY=http://127.0.0.1:3128 ollama serve

Then DNS and the link: check that the CDN hosts named in your errors resolve and respond, and prefer a wired link for a large pull. On Windows 10 WSL2, ollama's FAQ names Large Send Offload as a cause of slow model downloads.

5. Pull a smaller tag

Bytes are the denominator: the same slow path delivers a smaller model sooner, and the ollama library serves most models in several sizes and quantizations:

ollama pull llama3.1:8b

The trade is real: smaller tags are more heavily quantized, which costs accuracy, and this changes which weights you get, not how fast the path is.

6. Skip the registry: download the weights and import them

When a pull keeps dying near the end of 40 GB, stop asking the registry for it. Download the weights by a route you control, then hand ollama the local files:

FROM /path/to/model-directory
ollama create mymodel -f Modelfile

ollama documents this flow for GGUF files and for safetensors directories; the full worked example is below.

What ollama verifies, and what it does not

The digest check at the end of a pull is real verification, per layer: hash the file, compare it to the sha256 digest in the manifest the registry sent, delete on mismatch. The exact error text, with the wanted and got digests, is in issue 941.

What that proves: the bytes on disk match what the manifest described. What it does not prove: anything upstream. There is no signature in this flow, and a registry serving a tampered manifest with matching blobs passes this check.

That gap is why this archive works the way it does. Every payload here was verified against upstream Hugging Face at fetch time, with the exact revision pinned, and the file list travels as a minisign-signed manifest you re-check client side: per-file digests with the method labeled, sha256 for LFS files and sha1+size for git blobs. The verification walkthrough is the deep dive, and the verify page is the short version.

Pulling a Hugging Face model into ollama

Yes, you can pull a GGUF you found on huggingface.co straight into ollama, through the hf.co namespace. Both domain forms work:

ollama pull hf.co/username/repository
ollama pull huggingface.co/username/repository

Without a tag you get the default quantization, Q4_K_M when the repository has one, otherwise a reasonable pick. A quantization tag is case-insensitive; the full GGUF filename works as the tag for one specific file:

ollama pull hf.co/username/repository:Q8_0
ollama pull hf.co/username/repository:filename-Q4_K_M.gguf

Private repositories work the same way after one key step: ollama ships an ed25519 keypair, and you add the public half to your Hugging Face account's SSH keys. No Hugging Face token is involved on this path:

cat ~/.ollama/id_ed25519.pub

On the wire it is still a registry pull. The namespace resolves through a Docker Registry v2 style API: hf.co/v2/<repo>/manifests/<tag> redirects to huggingface.co, which answered 200 to an unauthenticated request when checked on 2026-09-01. After that the mechanics above apply unchanged. The namespace syntax and the key flow are documented in Hugging Face's ollama guide.

Since ollama 0.30 in June 2026, this is a documented path with a manual alternative: download the files yourself, write a Modelfile, create, run. The ollama announcement walks that flow.

Two boundaries. If huggingface.co itself is the slow part, the same crawl in a browser or the hf CLI, that is the Hugging Face throughput guide. If huggingface.co refuses the request, 401, 403 or 429, that is the error codes guide.

Getting weights in without waiting on the registry

The import from fix 6, worked with a real model. The catalog carries original safetensors trees, so this is the directory form.

  1. Pick the model in the catalog. This example uses NousResearch_Hermes-3-Llama-3.1-8B, 16.07 GB, Llama architecture, llama3 license.
  2. Download it by torrent and check it against the signed manifest. Client picks are on the help page, and the walkthrough is the verify page.
  3. Point a Modelfile at the downloaded directory, then create and run:
FROM /path/to/NousResearch_Hermes-3-Llama-3.1-8B
ollama create hermes3 -f Modelfile
ollama run hermes3

The directory form of FROM covers the common architectures, including Llama, Mistral, Gemma and Phi3; ollama's import documentation on docs.ollama.com lists the current set. A single GGUF file uses FROM /path/to/file.gguf instead: same flow, one file you fetched yourself.

One honest limit: this archive carries the original safetensors weights, not GGUF quantizations. A specific quant still has to come from its own source; the import above is how it gets in.

How long should the download take? One gigabyte takes about 1000 divided by your speed in MB/s; size and speed give the honest answer:

SpeedPer GBQwen_Qwen3-4B, 8.06 GBNousResearch_Hermes-3-Llama-3.1-8B, 16.07 GB
2 MB/s500 s67 min2.2 h
10 MB/s100 s13 min27 min
50 MB/s20 s2.7 min5.4 min

The slow reports behind this page sit at the top of that table or worse: 1.7 to 1.9 MB/s where other clients reached 50 to 300, roughly 10 Mbps with a 20 GB model taking about 10 hours, and under 1 KB/s on an 800 Mbps line. User reports from the issue tracker, not benchmarks, but they are why this page exists.

When the download finishes, leave the client running: a finished torrent seeds automatically, a share ratio of 2.0 or better is the goal, and what that sustains is on the contribute page. New to torrents as a distribution method? The AI model torrents guide covers legality and random-torrent risk, the magnet links guide the vocabulary, and requests is where to ask for a model that is not archived yet.

Frequently asked questions

Why is ollama pull so slow?

Usually one of four things. The registry or CDN host serving the blobs is slow from your network at that moment. The line is lossy, so 16 parallel parts fight each other. The pull has reached its small-blob tail. Or something between you and the host, like a proxy, DNS or a VPN, is breaking connections. A fast internet plan rules out none of these.

Why does ollama pull slow down at the end?

The big layers finish first, and the tail of a pull is small blobs. Each one needs its own signed URL inside a 30 second budget, so a problem that parallelism was hiding becomes visible near 95 percent. If the bar still moves, let it finish. If it errors, re-run the pull; the finished layers are kept.

If I stop an ollama pull, do I lose the download?

Not from stopping. Re-running the same pull resumes each part from where it stopped on disk. The real risk is the startup prune: if you stop the server and come back more than an hour later, leftover partial files older than an hour are deleted when the server starts. Setting OLLAMA_NOPRUNE before that restart protects them.

Why does my progress bar go backwards or the pull restart?

Two different things look alike. On a generic network error the client rolls back the bytes it counted for that part, so the bar drops even though the data on disk is kept. A pull that starts over from zero usually means the partial files were pruned, or the failure happened at the manifest stage, before any blob landed.

Is there a setting to make ollama download faster?

For GGUF blob pulls, no. The 16 part count and the 30 second timeouts are fixed in the source, and several variables recommended online are not in current ollama at all. What exists: OLLAMA_NOPRUNE to protect partials, HTTPS_PROXY on the server process when a proxy is the cause, and OLLAMA_MAX_TRANSFER_STREAMS, default 4, which only affects the newer safetensors engine path.

How do I pull a model from Hugging Face?

Use the hf.co namespace: ollama pull hf.co/username/repository. Add a quantization tag like :Q8_0, or the full GGUF filename as the tag, to pick a specific file; Q4_K_M is the default when present. Private GGUFs work once you add ollama's own public key to your Hugging Face account SSH keys. No Hugging Face token is involved.

Does ollama check that the model it downloaded is correct?

Yes, per layer. After the download it hashes the file and compares it to the sha256 digest in the manifest the registry sent, and deletes the file on mismatch. What that cannot tell you is whether that manifest itself deserved your trust: there is no signature in this flow, and nothing upstream of the registry is checked. Verifying weights against an independent signed record is a separate step.

Where are ollama models stored, and can I move them?

On macOS, ~/.ollama/models. On a Linux service install, /usr/share/ollama/.ollama/models. On Windows, C:\Users\yourname\.ollama\models. Set OLLAMA_MODELS to move the directory, and give the service user write access to the new location. Blobs are stored under their sha256 digest names, which is why a partially downloaded blob looks like a file called sha256-something-partial-N.