GGUF · 2026-11-05

ollama stop model — the five-minute squat

The chat ends and ollama still holds the model — 2.97 GiB for five measured minutes. Stop doors: ollama stop, keep_alive 0, --keepalive, OLLAMA_KEEP_ALIVE.

HUMANby @msvram13h7 min read

The compressed answer: closing the terminal, the chat window, or the API connection does not unload anything. The server holds the model warm so your next ask skips the load, and the hold runs on a five-minute timer by default. That timer is a good default you'll want to override on small boxes — and every lever you need ships in the box: a stop command, a per-request field, a CLI flag, one environment variable.

receipt · the witness
GET localhost:11434/api/ps — four minutes after the chat closed
{"models":[{"name":"qwen3:4b",
  "size":3186108660,
  "quantization_level":"Q4_K_M",
  "expires_at":"2026-11-05T13:25:41.680418376Z",
  "size_vram":0,
  "context_length":4096}]}
3,186,108,660 B ÷ 1,073,741,824 = 2.97 GiB resident · expiry stamped at ask time + 300 s

It's 13:20 on the bench. The model just spent 139 seconds thinking and answered "Hi there friend" — 974 tokens at 7.0 tok/s (974 ÷ 139.223, by hand; the rate fields don't always fill, so we divide). Then it stopped talking and kept the sofa warm. We polled /api/ps every 30 s. The answer came back resident at 13:22:09, 13:22:39, … 13:25:11. At 13:25:41 the room was empty — 300.0 seconds after the last token, exactly as stamped. RAM fell 3,542 → 473 MiB. The five-minute squat is real, timed, and enormous on a small box.

last token squat · 5:00 evicted keep 0 → now keep 60 → 1:00 keep −1 → never memory held after the conversation, by keep_alive
Fig 1 — the hold is a timer, not a state. The stamp in expires_at is the eviction minute.

How to stop an ollama model

The direct door: ollama stop takes a model name and unloads it immediately.

ollama run qwen3:4b "Reply with the single word: ok."
ollama ps                 # the model is resident
ollama stop qwen3:4b      # the eviction notice
ollama ps                 # no models

verify: ollama ps prints {"models":[]} after the stop — measured above, exit 0.

Over the API, the hold is a field on the request: "keep_alive": 0 answers first, then empties the room. One trip, no second call.

curl localhost:11434/api/chat -d '{
  "model": "qwen3:4b",
  "messages": [{"role":"user","content":"Reply with the single word: ok."}],
  "stream": false,
  "keep_alive": 0
}'

verify: the answer still returns ("content":"ok"), and /api/ps immediately prints {"models":[]} — measured: RAM stayed at 477 MiB.

Per-run, the CLI takes the same knob: ollama run qwen3:4b --keepalive 0 "…".

doorscopeunload timinghold after
ollama stop <model>one model, nowimmediate0 s
"keep_alive": 0this requestafter answering0 s
--keepalive 0this runafter answering0 s
--keepalive 300sthis run5 min after last ask5:00 — unit required (300 alone errors: missing unit in duration)
OLLAMA_KEEP_ALIVE=0every model, standingafter each ask0 s
OLLAMA_KEEP_ALIVE=-1every model, standingnever (manual stop)∞
no knob (default)every model5 min after last ask5:00
All rows measured on the bench below — none from docs.

How long does ollama keep a model loaded?

Five minutes, by default, counted from your last ask — every request resets the timer, which is why a long session never seems to let go. The measured ladder, one qwen3:4b on a 4-thread CPU box:

keep_aliveexpires_at shiftmeasured holdRAM after
default+300 s5:00.0 to the second3,542 → 473 MiB at eviction
0noneinstant, post-answer477 MiB
60+60 sgone at the 65 s poll~3 GiB → base
-1+293 years (stamped 2319-02-15)still resident at +90 sheld until stopped
env 2m+120 sper the stampheld 2:00
ollama 0.40.13 (Arch package; 0.40.14 tagged upstream 11-03) · qwen3:4b Q4_K_M, digest 359d7dd4 · 4 threads, 8 GiB RAM, KVM VM · last tested 2026-11-05

The honest column: this is a CPU box, and /api/ps said so — "size_vram": 0. On a GPU host the same model lands in VRAM and the same timer governs it; we don't print GPU numbers we didn't sit behind, and the squat's mechanics don't change with the address space.

ollama keep alive forever — the −1 and the environment variable

The ac block asks for this one by name: "keep_alive": -1 means never evict. Reloads vanish — at the cost of the RAM never coming back until you stop the model yourself. The standing form is OLLAMA_KEEP_ALIVE, read by the server at boot: -1 for forever, 2m for two minutes, 0 for none. On a systemd box that's a drop-in:

sudo systemctl edit ollama   # add:
[Service]
Environment="OLLAMA_KEEP_ALIVE=2m"
# then:
sudo systemctl daemon-reload && sudo systemctl restart ollama

verify: after the restart, one ask stamped expires_at at exactly +120 s — the env var beat the default on the measured run.

Numbers in the env are Go durations (300s, 5m, 1h), and the request field accepts the same strings. The per-request field always beats the env; the env always beats the default.

Does closing the terminal unload the model?

No. The client is a messenger; residency belongs to the server. Kill the chat, the REPL, or the curl, and the model stays warm for its five minutes. If you actually want everything gone, stop the server — sudo systemctl stop ollama — which frees the memory and takes the API door with it. That's the whole-house switch, and on a homelab timer it belongs in Mr Keepalive's ledger, not this one.

How to unload all models at once

No single command ships for it, so hand the witness list to the stop command in a loop — ollama ps has no machine format in 0.40.13 (--format json errors: unknown flag), so read /api/ps:

curl -s localhost:11434/api/ps | jq -r '.models[].model' \
  | xargs -r -n1 ollama stop
ollama ps   # empty table — the room is clear

verify: the loop ran on the bench — one resident qwen3:4b went in, the empty UNTIL table came out.

While a model squats, the plain table tells you what's held and for how long — ollama prints the remaining lease itself:

$ ollama ps
NAME       ID           SIZE    PROCESSOR    CONTEXT    RUNNER     UNTIL
qwen3:4b   359d7dd4...  3.2 GB  100% CPU     4096       llamacpp   4 minutes from now

When the squat is worth keeping

The five minutes exist because loads cost. After an eviction, our bench paid 2.05 s to get the model back (file cache warm) — cheap here, and the reason the default is warm. The honest ledger: on a box with RAM to spare, leave the squat alone; it's a feature that pre-loads your next ask. On a small box, it's the difference between a usable machine and one that swaps while you read. Measure your own hold with ollama ps, pick a rung from the ladder, and set the env once.

We metered this machine's other bill already: the per-ask cost of a model thinking it shouldn't (the thinking bill, November 1st — 866 tokens to say "Bug"), and the rent your context charges at load (KV cache quantization, November 4th). The squat is the third bill in the series — the one that runs between asks. The chat ends. The rent doesn't. Now you hold the eviction notice.

bench receipts: throwaway Arch VM (4 threads, 8 GiB, CPU-only), ollama 0.40.13, qwen3:4b Q4_K_M · polled /api/ps across every hold · VM destroyed same session