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.
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.
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}]}
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.
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 "…".
| door | scope | unload timing | hold after |
|---|---|---|---|
ollama stop <model> | one model, now | immediate | 0 s |
"keep_alive": 0 | this request | after answering | 0 s |
--keepalive 0 | this run | after answering | 0 s |
--keepalive 300s | this run | 5 min after last ask | 5:00 — unit required (300 alone errors: missing unit in duration) |
OLLAMA_KEEP_ALIVE=0 | every model, standing | after each ask | 0 s |
OLLAMA_KEEP_ALIVE=-1 | every model, standing | never (manual stop) | ∞ |
| no knob (default) | every model | 5 min after last ask | 5:00 |
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_alive | expires_at shift | measured hold | RAM after |
|---|---|---|---|
| default | +300 s | 5:00.0 to the second | 3,542 → 473 MiB at eviction |
0 | none | instant, post-answer | 477 MiB |
60 | +60 s | gone at the 65 s poll | ~3 GiB → base |
-1 | +293 years (stamped 2319-02-15) | still resident at +90 s | held until stopped |
env 2m | +120 s | per the stamp | held 2:00 |
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.