Tutorials  /  AI/ML

Managing Ollama Models: Updates, Cleanup and Disk Space

LLudwig · August 2026 ·11 min read ·AI/ML, Tutorial

Ollama makes it easy to pull models and then forget about them. A few weeks later ollama list shows a dozen tags, the root filesystem sits at 95 percent, and it is no longer obvious which blobs still belong to a model you actually use. This tutorial covers updating models and the engine, removing what you no longer need, and moving the model store to a larger volume.

Where does Ollama store its models?

Ollama stores model layers as content-addressed blobs under /usr/share/ollama/.ollama/models when it runs as a systemd service, and under ~/.ollama/models for a user-level installation on Linux or macOS.

The directory has two subtrees. blobs/ holds the actual data as files named sha256-<digest>, one per layer: weights, template, license, parameters. manifests/registry.ollama.ai/library/<model>/<tag> holds a small JSON file per tag that lists the digests belonging to that tag. Two tags that share a weights layer, for example llama3.1:8b and llama3.1:latest, point at the same blob. That is why the disk is not the sum of the sizes shown in ollama list.

Prerequisites

  • A Linux host with Ollama 0.3 or newer; check with ollama -v
  • A user with sudo rights
  • At least 20 GB free on the volume holding the model directory
  • Optional but relevant for inference speed: an NVIDIA GPU, for example on a GPU instance sized for LLM inference

All commands below assume the systemd service installation created by the official install script. For a user-level install, replace /usr/share/ollama/.ollama with ~/.ollama and drop the sudo.

Take inventory of installed models

Start every cleanup with an inventory, because the size column in ollama list counts shared layers once per model and therefore overstates the total.

Console
$ ollama list
NAME                ID              SIZE      MODIFIED
llama3.1:8b         42182419e950    4.7 GB    3 weeks ago
llama3.1:latest     42182419e950    4.7 GB    3 weeks ago
qwen2.5-coder:14b   9ec8897f747e    9.0 GB    6 days ago
mistral:7b          f974a74358d6    4.1 GB    2 months ago

Four commands cover the whole picture:

Command Shows Use it for
ollama list installed tags, ID, nominal size tag audit
ollama ps loaded models, memory, expiry RAM and VRAM audit
ollama show llama3.1:8b quantisation, context length, parameters verifying a tag
sudo du -sh /usr/share/ollama/.ollama/models real disk usage before and after cleanup

In the example above, llama3.1:8b and llama3.1:latest share the same ID 42182419e950. They occupy 4.7 GB together, not 9.4 GB. Removing one of the two tags frees nothing.

GPU

Matching infrastructure at centron

Dedicated NVIDIA GPUs from German data centres, billed by the hour and ready in minutes. Rent a GPU server →

How do you update an Ollama model?

Run ollama pull <model>:<tag> to update a model: Ollama fetches the current manifest for that tag from the registry and downloads only the layers whose sha256 digests differ from the local copy.

Console
$ ollama pull llama3.1:8b
pulling manifest
pulling 667b0c1932bc: 100% ▕████████████▏ 4.9 GB
verifying sha256 digest
writing manifest
success

If nothing changed upstream, the pull finishes in a second and no bytes are transferred. This makes ollama pull safe to run on a schedule. Two details matter:

  • Pinned tags still move. A tag such as 8b is a pointer, not an immutable digest. Vendors republish tags after quantisation fixes, so a pull can replace the weights under a stable-looking name.
  • latest is not special. It is only the default tag when you omit one. Pull it explicitly if you rely on it.

Compare the ID column before and after the pull. If the ID changed, the model was genuinely updated and the previous weights layer is now unreferenced.

The following flow describes the decision path from inventory to freed disk space:

graph TD
    A["ollama list"] --> B{"Tag still needed?"}
    B -- No --> C["ollama rm model:tag"]
    B -- Yes --> D["ollama pull model:tag"]
    D --> E{"ID changed?"}
    E -- No --> F["Already up to date"]
    E -- Yes --> G["Old layer now unreferenced"]
    C --> H["Compare blobs against manifests"]
    G --> H
    H --> I["Delete orphaned sha256-* files"]

Update the Ollama engine

The engine and the models are updated separately, so a fresh model tag does not imply a current runtime. New model architectures frequently require a newer Ollama version, and an outdated engine fails with an error such as Error: unable to load model.

On Linux, re-run the official install script. It detects the existing installation, replaces the binary and restarts the service:

Console
$ curl -fsSL https://ollama.com/install.sh | sh
$ ollama -v
ollama version is 0.12.3

For the container image, pull and recreate instead:

Console
$ docker pull ollama/ollama:latest
$ docker stop ollama && docker rm ollama
$ docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

The named volume ollama keeps the models, so recreating the container does not re-download anything.

Remove models and reclaim disk space

Delete a model with ollama rm <model>:<tag>. This removes the manifest for that tag and every layer that no other manifest still references.

Console
$ ollama rm mistral:7b
deleted 'mistral:7b'
$ sudo du -sh /usr/share/ollama/.ollama/models
18G /usr/share/ollama/.ollama/models

Remove several tags in one call:

Console
$ ollama rm mistral:7b llama2:13b codellama:7b

Before you delete anything, check what is running. ollama ps lists models currently held in memory, and deleting a model that is loaded leaves the running request in an undefined state:

Console
$ ollama ps
NAME               ID              SIZE     PROCESSOR    UNTIL
qwen2.5-coder:14b  9ec8897f747e    11 GB    100% GPU     4 minutes from now

Why is the models directory larger than ollama list suggests?

The models directory grows beyond the total reported by ollama list when blob files remain on disk that no manifest references any more, typically after interrupted pulls, a killed service during a write, or manual edits under manifests/.

Ollama removes unreferenced layers during ollama rm and after a successful ollama pull, but that cleanup only runs when the operation completes. A pull aborted by a full disk or a Ctrl+C leaves partial blobs behind. There is no ollama prune subcommand, so audit the directory yourself.

Find orphaned blobs

The script collects every digest referenced by a manifest, compares it against the files in blobs/ and reports the difference:

bash
#!/usr/bin/env bash
set -euo pipefail
ROOT="${OLLAMA_MODELS:-/usr/share/ollama/.ollama/models}"
ref=$(mktemp)
have=$(mktemp)
grep -rhoE 'sha256:[a-f0-9]{64}' "$ROOT/manifests" | tr ':' '-' | sort -u > "$ref"
find "$ROOT/blobs" -type f -name 'sha256-*' -printf '%f\n' | sort -u > "$have"
comm -13 "$ref" "$have" > /tmp/ollama-orphans.txt
echo "orphaned blobs: $(wc -l < /tmp/ollama-orphans.txt)"
xargs -a /tmp/ollama-orphans.txt -I{} du -h "$ROOT/blobs/{}" 2>/dev/null || true

Save it as /usr/local/bin/ollama-orphans.sh, make it executable and run it with sudo:

Console
$ sudo chmod +x /usr/local/bin/ollama-orphans.sh
$ sudo /usr/local/bin/ollama-orphans.sh
orphaned blobs: 2
3.8G    /usr/share/ollama/.ollama/models/blobs/sha256-8934d96d3f08...
1.1G    /usr/share/ollama/.ollama/models/blobs/sha256-a1b2c3d4e5f6...

Review the list, then stop the service and delete the files. Stopping first prevents a race with a pull that is writing a new blob:

Console
$ sudo systemctl stop ollama
$ sudo xargs -a /tmp/ollama-orphans.txt -I{} rm -v "/usr/share/ollama/.ollama/models/blobs/{}"
$ sudo systemctl start ollama

If the list is empty, the directory is consistent and the space is genuinely occupied by models you still have installed.

Move the model directory to a larger volume

When a 7B model costs roughly 4.7 GB and a 70B model in Q4 quantisation costs around 40 GB, the root filesystem stops being the right place. Set OLLAMA_MODELS through a systemd drop-in and point it at a dedicated volume. On scalable Linux VMs you can attach an additional block device and mount it at /mnt/models before you start.

Copy the existing data first, preserving ownership:

Console
$ sudo systemctl stop ollama
$ sudo rsync -aHAX /usr/share/ollama/.ollama/models/ /mnt/models/
$ sudo chown -R ollama:ollama /mnt/models

Create the override with sudo systemctl edit ollama.service and add:

ini
[Service]
Environment="OLLAMA_MODELS=/mnt/models"

Reload and restart:

Console
$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama
$ ollama list

If ollama list returns the same models as before, the move worked and you can delete the old directory. The most common failure here is ownership: the service runs as the ollama user and reports permission denied if the new path belongs to root.

Free memory without deleting models

Disk space and VRAM are separate problems. A model that is loaded occupies GPU memory until its keep-alive timer expires, which defaults to 5 minutes. Unload it immediately:

Console
$ ollama stop qwen2.5-coder:14b

To change the default behaviour, set OLLAMA_KEEP_ALIVE in the same drop-in file. A value of -1 keeps models resident indefinitely, 0 unloads them right after each request:

ini
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_MAX_LOADED_MODELS=2"

OLLAMA_MAX_LOADED_MODELS caps how many models stay in memory at once, which prevents a second large model from pushing the first out of GPU memory into slower CPU inference.

Verification

Run three checks after a cleanup:

Console
$ ollama list
$ ollama run llama3.1:8b "reply with OK"
OK
$ df -h /mnt/models
Filesystem      Size  Used Avail Use% Mounted on
/dev/vdb1       200G   18G  173G   10% /mnt/models

The model list should contain exactly the tags you kept, a test prompt must return a response, and the usage on the model volume should match the sum from ollama list minus shared layers.

Troubleshooting

  • Error: permission denied after moving the directory. The service user cannot read the new path. Run sudo chown -R ollama:ollama /mnt/models and restart the service.
  • A pull aborts with no space left on device. Ollama needs room for the download plus the final blob. Free space first, then re-run the pull and check for orphans with the script above, since the aborted download leaves partial files behind.
  • ollama rm reports success but nothing is freed. Another tag still references the same layers. Check the ID column in ollama list and remove the remaining tags that share it.

Wrap-up

A maintenance pass on an Ollama host is three commands: ollama pull for the tags in use, ollama rm for the ones that are not, and a blob-versus-manifest comparison for the remainder. Run the inventory before each cleanup, because shared layers make the nominal sizes in ollama list unreliable as a disk budget. If the model store keeps growing, move it to its own volume once instead of pruning the root filesystem every few weeks.

Read next

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

Ludwig Technische Redaktion

Schreibt bei centron über Linux-Administration, Container und Datenbanken – mit Fokus auf Anleitungen, die im Betrieb tatsächlich funktionieren.

Kategorie AI/ML
Teilen
Noch offene Fragen?

Our team will help you with your specific setup - in German or English, by people who run the platform themselves.

War dieses Tutorial hilfreich?

Your answer is stored anonymously and helps us improve our tutorials.

Kommentare

No comments yet - be the first to ask a question about this tutorial.

Sign in to comment

Comments are open to centron customers. Sign in to your account to ask a question about this tutorial.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren