SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-22

Giữ model Ollama trong memory bằng keep_alive

Ollama mặc định dỡ model sau 5 phút idle. Đặt keep_alive trong request hoặc systemd để request tiếp theo không phải load lại weights từ disk.

Vì sao Ollama dỡ model khỏi bộ nhớ sau vài phút?

Ollama giữ model trong bộ nhớ trong 5 phút sau request cuối cùng, rồi giải phóng model. Request tiếp theo phải đọc weights từ disk và map lại chúng vào RAM hoặc VRAM, nên bị chậm trước khi token đầu tiên xuất hiện. Vì vậy, chat UI hoặc coding agent có thể phản hồi nhanh, im lặng một lúc, rồi lại chậm ở message tiếp theo. Không có gì bị hỏng. Timer idle đã hết hạn.

Timer này có tên là keep_alive. Timer áp dụng riêng cho từng model và được khởi động lại mỗi khi một request hoàn tất. Model đang trả lời request sẽ không bao giờ bị dỡ khỏi bộ nhớ, vì server chỉ hết hạn model khi model đó không có request đang hoạt động. Tính đến tháng 8 năm 2026, giá trị mặc định là 5 phút và áp dụng cho mọi model mà server này load.

Có 2 nơi để đặt keep_alive: trong từng request hoặc làm giá trị mặc định của server. systemd drop-in giúp giá trị mặc định của server vẫn được giữ sau khi restart. Hướng dẫn này giả định Ollama đã chạy dưới dạng service. Nếu chưa, hãy bắt đầu với cài đặt Ollama trên VPS rồi quay lại.

Model nào hiện đang được giữ trong memory và khi nào chúng hết hạn?

ollama ps
NAME        ID              SIZE      PROCESSOR    CONTEXT    UNTIL
qwen3:8b    500a1f067a9f    6.6 GB    100% GPU     4096       4 minutes from now

Kết quả rỗng nghĩa là chưa có model nào được load, nên request tiếp theo phải chịu toàn bộ thời gian load. PROCESSOR cho biết weights được đặt ở đâu. 100% GPU và 100% CPU là các trường hợp rõ ràng. Giá trị dạng 25%/75% CPU/GPU nghĩa là model không vừa VRAM, nên một phần chạy trên processor và thời gian generation sẽ lâu hơn.

UNTIL là bộ đếm ngược. Giá trị này in ra thời gian tương đối như 4 minutes from now. Nó in Forever khi model được load với keep_alive âm. Trong khoảng thời gian ngắn khi server đang unload model, nó in Stopping....

Bộ cột đã thay đổi giữa các bản release, vì vậy hãy đọc header thay vì đếm số field trong script. Với mọi tác vụ tự động hóa, hãy gọi API:

curl -s http://localhost:11434/api/ps

Mỗi entry có expires_at, một timestamp tuyệt đối như 2026-08-09T14:38:31.83753Z, và size_vram, tức phần của model đang nằm trong GPU memory. Giá trị size_vram bằng 0 nghĩa là model đang chạy trên CPU.

Chi phí thực tế của việc reload

Không nên đoán. Ollama báo thời gian load trong mọi response, dưới dạng load_duration, tính bằng nanosecond.

sudo apt install -y jq
ollama stop qwen3:8b
curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "prompt": "hi", "stream": false}' | jq '{load_duration, total_duration}'
curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "prompt": "hi", "stream": false}' | jq '{load_duration, total_duration}'

Lần gọi đầu tiên load model, nên load_duration có giá trị lớn. Chia giá trị này cho 1000000000 để đọc theo đơn vị giây. Lần gọi thứ hai chạy khi model vẫn còn trong memory và báo một giá trị nhỏ hơn nhiều. Khoảng chênh giữa hai giá trị đó là thời gian mọi user phải chờ sau khi timer hết hạn. Đây cũng là lý do chính để thay đổi keep_alive. Phần lớn khoảng chênh này là thời gian đọc từ disk. Vì vậy, nếu bạn đã chuyển thư mục model sang volume thứ hai, tốc độ của volume đó quyết định thời gian tối thiểu cho mỗi lần cold load. Để đo tốc độ generation ở cả hai phía của khoảng chờ này, xem cách đo số token mỗi giây trên máy của bạn.

Giữ model Ollama trong memory cho một request

Gửi keep_alive cùng với request. Thiết lập này áp dụng cho model đó ngay khi request hoàn tất.

curl -s http://localhost:11434/api/chat -d '{
  "model": "qwen3:8b",
  "messages": [{"role": "user", "content": "hello"}],
  "keep_alive": "30m"
}'

Có 4 dạng giá trị được chấp nhận:

  • chuỗi thời lượng: "30m", "24h", "90s"
  • số nguyên không kèm đơn vị, được hiểu là số giây: 3600
  • giá trị âm, -1 hoặc "-1m", nghĩa là không đặt idle timeout
  • 0, nghĩa là unload ngay khi request này hoàn tất

Giá trị trên request sẽ ghi đè server default theo cả hai hướng. Điều này quan trọng hơn bạn nghĩ: client gửi keep_alive riêng sẽ được ưu tiên hơn mọi giá trị bạn đã cấu hình trên server.

Bạn cũng có thể load model mà không generate nội dung nào. Chỉ gửi tên model. Server sẽ load model và trả về response rỗng cùng với "done": true.

curl -s http://localhost:11434/api/generate -d '{"model": "qwen3:8b", "keep_alive": "30m"}'

Đó là command cần chạy sau khi reboot hoặc sau khi pull model mới, để request đầu tiên của user thực sự không phải chờ load model. CLI cũng làm được việc tương tự bằng một flag:

ollama run --keepalive 30m qwen3:8b "hello"

Giữ model đã load mặc định bằng OLLAMA_KEEP_ALIVE

Server đọc OLLAMA_KEEP_ALIVE khi khởi động và dùng giá trị này cho mọi model không có giá trị riêng. Biến này dùng cùng các dạng như field trong request, nên 30m, 3600 và -1 đều hoạt động.

Điểm cần lưu ý là biến môi trường phải nằm trong environment của tiến trình nào. Chạy export OLLAMA_KEEP_ALIVE=30m trong phiên SSH của bạn không có tác dụng, vì bản cài đặt dạng package chạy server dưới dạng systemd service, bằng user riêng và environment riêng. Login shell của bạn không chia sẻ environment với service đó. Đây là lý do phổ biến nhất khiến thiết lập này có vẻ bị bỏ qua.

Giữ cấu hình sau khi restart bằng systemd drop-in

sudo systemctl edit ollama.service

Editor mở ra với 2 marker comment. Nhập nội dung giữa 2 marker này: systemd sẽ bỏ qua mọi nội dung bạn viết bên dưới marker thứ 2.

[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"

Lệnh lưu sẽ ghi vào /etc/systemd/system/ollama.service.d/override.conf. Đây là drop-in, không phải chỉnh sửa unit đã được package cung cấp. Vì vậy, khi package Ollama upgrade và thay thế ollama.service, cấu hình của bạn vẫn được giữ nguyên. Nếu drop-in và unit file còn mới với bạn, hướng dẫn về systemd service và timer giải thích cơ chế này.

sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environment

Lệnh cuối cùng in ra environment mà service thực sự sẽ chạy với. Nếu OLLAMA_KEEP_ALIVE=30m không xuất hiện trong dòng đó, drop-in chưa được áp dụng. Nguyên nhân gần như luôn là thiếu header [Service] hoặc đã nhập các dòng bên dưới marker. Bản thân thao tác restart sẽ giải phóng mọi model đã load, nên request tiếp theo phải load lạnh. Hãy warm up bằng lệnh preload ở trên.

Chi phí để giữ model luôn trong memory

Cột SIZE trong ollama ps là lượng memory được giữ trong toàn bộ thời gian idle, không chỉ trong lúc xử lý request. Một model 8B với quantisation 4-bit thường dùng khoảng 5 đến 6 GB. Model 27B là một bài toán khác, và cách tính memory để chạy model này trên VPS chỉ có CPU đáng được xem xét trước khi bạn quyết định giữ nó luôn trong memory. Đặt keep_alive thành -1 nghĩa là bạn quyết định model luôn được ưu tiên hơn mọi thứ khác trên máy. Trên VPS nhỏ, đây là sự đánh đổi trực tiếp với database, web app và các build job.

Hãy xem số liệu thực tế thay vì chỉ tin vào con số ước tính. Chạy lệnh này khi model đang được load, sau đó chạy lại sau ollama stop:

free -h

Cột available là lượng memory mà kernel vẫn có thể cấp cho một process mới. Trên máy có NVIDIA GPU, nvidia-smi cho thấy tình trạng tương tự trong VRAM. Nếu máy hết memory, kernel sẽ kill một process để thu hồi tài nguyên:

sudo dmesg -T | grep -i "out of memory"

Một dòng có tên ollama nghĩa là model server đã bị kill. Một dòng có tên database của bạn nghĩa là model đã được ưu tiên và một thành phần quan trọng đã bị mất. Cả hai kết quả đều xuất phát từ cùng một quyết định: đặt thời gian keep-alive dài trên một máy không còn headroom.

Có 2 chi phí ở đây dễ bị bỏ qua. Context length lớn hơn sẽ reserve một KV cache lớn hơn (key value cache, trạng thái attention trên mỗi token mà model giữ trong lúc generate), và cache này nằm trong kích thước resident. Kích thước cache phụ thuộc vào num_ctx, vì vậy tăng context window sẽ làm tăng lượng memory mà model resident giữ trong toàn bộ thời gian idle, không chỉ lúc model trả lời. OLLAMA_NUM_PARALLEL lớn hơn 1 sẽ reserve cache này một lần cho mỗi parallel slot. Nếu bạn định phục vụ nhiều người bằng một model, hãy tính memory theo số slot, không chỉ theo riêng phần weights.

Thiết lập mặc định hợp lý: một model trên máy còn headroom có thể dùng -1. Máy dùng chung nên đặt window bao phủ khoảng thời gian giữa các request của bạn, chẳng hạn 30m, để memory được trả lại khi bạn ngừng làm việc.

Gỡ model ngay lập tức

ollama stop qwen3:8b

Lệnh không trả về output nào và model biến mất khỏi ollama ps. Nếu tên model chưa được load, lệnh trả về couldn't find model "qwen3:8b" to stop. Dạng API là một request không có prompt và đặt keep_alive thành 0:

curl -s http://localhost:11434/api/chat -d '{"model": "qwen3:8b", "messages": [], "keep_alive": 0}'

Response chứa "done_reason": "unload". Dùng cách này thay vì restart service. systemctl restart ollama cũng giải phóng memory, nhưng gỡ mọi model đang được load và dừng mọi request đang chạy.

Chạy nhiều model trên một server

OLLAMA_MAX_LOADED_MODELS giới hạn số model được giữ loaded cùng lúc. Tính đến August 2026, giá trị mặc định là ba model trên mỗi GPU, hoặc ba model trên máy chỉ có CPU. Giới hạn này đếm số model, nhưng bộ nhớ mới là giới hạn thực tế. Vì vậy, một model lớn thứ hai có thể bị từ chối cấp chỗ từ lâu trước khi đạt đến ba model.

Khi có yêu cầu load model mới nhưng không đủ bộ nhớ, scheduler sẽ unload một model đang resident để giải phóng chỗ. Scheduler ưu tiên model không có request đang hoạt động. Nó cũng có thể evict model dù timer của model đó chưa hết hạn, kể cả model được load bằng -1. Vì vậy, giá trị keep_alive âm có nghĩa là không có idle timeout. Giá trị này không pin weights để ngăn request của model khác sử dụng bộ nhớ.

Quyết định đó được ghi log ở debug level. Thêm dòng Environment="OLLAMA_DEBUG=1" thứ hai vào cùng drop-in, restart, rồi monitor:

sudo journalctl -u ollama -f

Một dòng cho biết runner bị unload để giải phóng chỗ, nằm ngay cạnh request đã kích hoạt việc đó, cho thấy hai model này không thể cùng chạy trên máy này. Cách xử lý là chạy ít model hơn trên máy này, hoặc đặt window dài cho model cần phản hồi nhanh và dùng 0 cho model chỉ được gọi không thường xuyên.

Hướng dẫn vẫn dùng được sau các bản release tiếp theo

Ollama thường xuyên phát hành bản release mới và các giá trị mặc định có thể thay đổi. Vì vậy, hãy kiểm tra build đang chạy thay vì ghi nhớ các con số:

ollama --version
ollama serve --help

ollama serve --help liệt kê các biến môi trường mà build đó thực sự đọc, trong đó có OLLAMA_KEEP_ALIVE. Có 2 quy tắc vẫn đúng qua các bản release và có thể dùng làm cơ sở cấu hình. Giá trị trong request sẽ ưu tiên hơn giá trị mặc định của server. Và ollama ps mới phản ánh chính xác những gì đã được load, bất kể file cấu hình khai báo thế nào.

Nếu một editor hoặc agent điều khiển server, hãy kiểm tra client đó gửi gì trước khi quy trách nhiệm cho server. Trỏ coding agent vào Ollama server của bạn giải thích nơi lưu các thiết lập trong request đó.

FAQ

Vì sao Ollama unload model sau 5 phút?

Năm phút là keep_alive mặc định, tức bộ đếm thời gian idle mà Ollama bắt đầu khi một request hoàn tất. Khi bộ đếm hết thời gian, server giải phóng các weight. Request tiếp theo phải load lại chúng từ disk, và quá trình này tạo ra khoảng dừng mà bạn nhận thấy. Tăng thời gian này cho một request bằng cách gửi "keep_alive": "30m" trong JSON body, hoặc áp dụng cho toàn bộ server bằng biến môi trường OLLAMA_KEEP_ALIVE.

Làm thế nào để giữ model Ollama luôn được load trong memory?

Dùng giá trị âm: "keep_alive": -1 trong request, hoặc OLLAMA_KEEP_ALIVE=-1 cho server. Khi đó ollama ps hiển thị Forever trong cột UNTIL. Cách này chỉ tắt bộ đếm idle, không thay đổi điều gì khác. Nếu có request dùng model khác và memory không đủ, scheduler vẫn unload model này để giải phóng chỗ.

Vì sao OLLAMA_KEEP_ALIVE bị bỏ qua?

Kiểm tra nơi bạn đặt biến này. Chạy systemctl show ollama --property=Environment. Nếu biến không xuất hiện trong output đó, server chưa bao giờ nhận được nó, vì biến được export trong shell của bạn không được truyền đến service systemd. Đặt biến bằng sudo systemctl edit ollama.service, sau đó chạy sudo systemctl daemon-reload và sudo systemctl restart ollama. Nguyên nhân khác là client tự gửi keep_alive trong request, ghi đè giá trị mặc định của server.

Làm thế nào để giải phóng memory mà không restart Ollama?

ollama stop qwen3:8b unload ngay model đó, đồng thời giữ server và mọi model khác đang được load tiếp tục chạy. Qua API, gửi một request không có prompt và có "keep_alive": 0. Phản hồi sẽ trả về "done_reason": "unload". Xác nhận bằng ollama ps; model đó không còn được liệt kê.