TL;DR
When you switch between models in Ollama, the service unloads the current GGUF file from memory and loads the new one from disk. Large models like llama3.1:70b or mixtral:8x7b can exceed 40GB, causing sustained disk reads that pin your SSD at maximum utilization. This becomes especially problematic when multiple users or applications trigger rapid model switches, creating a cascade of disk I/O that degrades system responsiveness.
The root cause is straightforward: Ollama stores models in /usr/share/ollama/.ollama/models by default, and each switch requires reading gigabytes from disk into RAM. If your system lacks sufficient memory, the kernel may also swap existing data to disk, compounding the problem. The OLLAMA_NUM_GPU environment variable controls how many GPU layers to offload, but setting it too high on systems with limited VRAM forces frequent model reloads as the GPU memory fills.
Three approaches mitigate this issue. First, mount your model directory on tmpfs to eliminate physical disk I/O entirely – this requires enough RAM to hold your active models. Second, implement a preloading strategy where you keep frequently-used models in memory by sending periodic requests to Ollama’s API on port 11434. Third, tune OLLAMA_NUM_GPU to balance GPU offloading with memory constraints, preventing the swap thrashing that occurs when the system runs out of physical RAM.
Monitor disk I/O with iostat -x 1 during model switches to identify bottlenecks. Watch for sustained writes to your swap partition, which indicates memory pressure forcing Ollama to reload models repeatedly. Adjusting these parameters based on your actual hardware capabilities prevents the disk saturation that makes model switching unusable in production environments.
Understanding the Disk Thrashing Problem
When you switch between models in Ollama, the system must load entirely new GGUF files from disk into RAM. A typical 7B parameter model like Mistral or Llama 2 weighs in at 4-8GB depending on quantization level, while 13B models reach 8-16GB, and 70B models can exceed 40GB. Each model switch triggers a complete read operation from your SSD.
The disk thrashing occurs because Ollama’s model loading pipeline follows a specific sequence: it first checks if the requested model exists in OLLAMA_MODELS (default ~/.ollama/models), reads the model manifest, then streams the entire GGUF file into system memory before initializing the inference engine. During this window, your SSD experiences sustained sequential reads at maximum throughput.
When available RAM drops below the model size plus operating system overhead, Linux begins swapping existing memory pages to disk. This creates a vicious cycle – Ollama reads the new model from SSD while the kernel simultaneously writes displaced memory pages back to the same drive. You can observe this with:
iostat -x 1
Watch for the %util column hitting 100 and await times spiking above 50ms during model switches.
The situation worsens with concurrent requests. If your application switches from llama2:7b to codellama:13b while the previous model still occupies RAM, the kernel must evict the old model’s memory pages before loading the new one. This doubles the disk I/O – one write pass to clear space, one read pass to load the replacement.
Modern NVMe drives handle sequential operations efficiently, but the random I/O patterns from memory pressure combined with large file reads create contention at the block device level. The result: temporary system unresponsiveness and degraded performance for all disk-dependent processes.
Monitoring Disk I/O During Model Operations
When Ollama switches between models, the disk I/O spike often goes unnoticed until your system becomes unresponsive. Three command-line tools provide real-time visibility into what’s actually happening at the storage layer.
Install iotop to see which processes are hammering your SSD:
sudo apt install iotop
sudo iotop -o -a
The -o flag shows only processes performing I/O, while -a displays accumulated totals. When you run ollama run llama3.1:70b after using a different model, watch for the ollama process spiking to several hundred MB/s read operations. This indicates model loading from disk rather than memory.
Quantifying Disk Activity with iostat
The iostat utility from sysstat reveals device-level metrics:
sudo apt install sysstat
iostat -x 2
Monitor the %util column during model switches. Values approaching 100 percent confirm disk saturation. The await metric shows average wait time in milliseconds – spikes above 50ms during model loads indicate your SSD is the bottleneck, not CPU or RAM.
Continuous Monitoring with dstat
For a combined view of disk, network, and system resources:
sudo apt install dstat
dstat -tdD total,nvme0n1 5
Replace nvme0n1 with your actual device name from lsblk. Run this in a separate terminal while switching models via the Ollama API on port 11434. The disk read column will show sustained high throughput when Ollama loads model weights from storage.
Caution: These monitoring commands require root privileges. Verify you’re running them on the correct storage device before making optimization decisions based on the output. Misidentifying your system disk versus a data volume leads to incorrect conclusions about where the bottleneck exists.
Model Caching Strategies and Memory Management
Ollama keeps models in memory after first load, but its retention behavior depends on available RAM and concurrent model requests. By default, Ollama unloads models when memory pressure increases or when switching to a different model that requires the freed resources. This triggers disk reads from your SSD, causing the usage spikes you observe.
When you run ollama run llama3.1:8b, Ollama loads the model into RAM and keeps it there until another model needs the space. If you immediately switch to ollama run mistral:7b, the first model may be evicted to make room. Each eviction-and-reload cycle hammers your SSD with sequential reads of multi-gigabyte GGUF files.
Monitor which models stay resident using ollama ps. This shows currently loaded models and their memory consumption. If you frequently switch between three or four models, ensure your system has enough RAM to keep them all loaded simultaneously – typically 8GB per 7B parameter model at Q4 quantization.
Preventing Unnecessary Unloads
Set OLLAMA_MODELS to a directory on a tmpfs mount for faster access, though this still requires initial load from disk:
export OLLAMA_MODELS=/mnt/ramdisk/ollama-models
sudo mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=32G tmpfs /mnt/ramdisk
For production systems, pre-load frequently-used models by sending a simple request to each via the REST API on port 11434:
curl http://localhost:11434/api/generate -d '{"model":"llama3.1:8b","prompt":"test","stream":false}'
curl http://localhost:11434/api/generate -d '{"model":"mistral:7b","prompt":"test","stream":false}'
This keeps both models resident in RAM, eliminating reload cycles during normal operation. Validate these commands in a test environment before automating them in production workflows.
Implementing tmpfs and RAM Disk Solutions
Moving Ollama’s model storage to tmpfs eliminates SSD write amplification during model switching by keeping all model data in RAM. This approach works best for systems with sufficient memory to hold your active model set – typically 32GB or more for running multiple 7B parameter models.
First, stop the Ollama service and create a tmpfs mount point. The size parameter should match your available RAM minus system overhead:
sudo systemctl stop ollama
sudo mkdir -p /mnt/ollama-tmpfs
sudo mount -t tmpfs -o size=24G,mode=0755 tmpfs /mnt/ollama-tmpfs
Make the mount persistent across reboots by adding this line to /etc/fstab:
tmpfs /mnt/ollama-tmpfs tmpfs size=24G,mode=0755 0 0
Configuring Ollama to Use RAM Storage
Update the Ollama service configuration to point OLLAMA_MODELS at your tmpfs mount. Edit /etc/systemd/system/ollama.service or create an override file:
sudo systemctl edit ollama
Add these lines in the override section:
[Service]
Environment="OLLAMA_MODELS=/mnt/ollama-tmpfs"
Reload systemd and restart Ollama:
sudo systemctl daemon-reload
sudo systemctl start ollama
Pre-loading Models into RAM
Pull your frequently-used models into the tmpfs location:
ollama pull llama3.2:3b
ollama pull mistral:7b
ollama pull codellama:7b
Monitor RAM usage with free -h to ensure you maintain adequate headroom. The tmpfs mount will consume RAM proportional to stored model files, so avoid pulling large model collections that exceed your available memory.
Caution: tmpfs contents disappear on reboot. Consider scripting model pulls at startup or maintaining a persistent copy on SSD that you rsync to tmpfs during boot for faster initialization.
Optimizing Model Loading Parameters
The OLLAMA_NUM_GPU environment variable controls how many GPU devices Ollama uses for inference. Setting this incorrectly forces the system to fall back on CPU processing, which triggers excessive memory paging and SSD thrashing during model switches.
Check your available GPUs first:
nvidia-smi --list-gpus
For a single-GPU system, explicitly set the variable:
export OLLAMA_NUM_GPU=1
sudo systemctl restart ollama
Multi-GPU systems benefit from specifying which devices to use. If you have two GPUs but want to reserve one for other workloads:
export CUDA_VISIBLE_DEVICES=0
export OLLAMA_NUM_GPU=1
Preventing Memory Swapping
When Ollama loads a new model while another is still in memory, the kernel may swap older model data to disk. This creates the SSD usage spike you observe. Configure system memory limits to prevent this behavior.
Edit /etc/systemd/system/ollama.service and add memory constraints:
[Service]
MemoryMax=24G
MemoryHigh=20G
This keeps Ollama within defined boundaries. When approaching MemoryHigh, the system applies pressure before hitting the hard limit, giving Ollama time to unload the previous model cleanly.
For systems with limited RAM, reduce concurrent model retention:
export OLLAMA_MAX_LOADED_MODELS=1
This forces Ollama to fully unload the previous model before loading the next, eliminating overlap that causes memory pressure.
Caution: AI-generated tuning recommendations often suggest non-existent parameters like OLLAMA_NUM_GPU or incorrect memory values. Always verify environment variables against official Ollama documentation before applying them to production systems. Test changes on a development instance first, monitoring disk I/O with iostat -x 1 during model switches to confirm the optimization reduces SSD activity.
Installation and Configuration Steps
Start by installing iotop and iostat to track real-time disk I/O during model switches:
sudo apt install sysstat iotop -y
Monitor disk activity while switching models:
sudo iotop -o -b -n 3
iostat -x 2 5
These commands reveal which processes generate write spikes. Watch for ollama processes showing high write throughput during model loading.
Configuring tmpfs for Model Cache
Create a RAM-backed filesystem to reduce SSD wear during frequent model switches. Allocate 16GB for models under 13B parameters:
sudo mkdir -p /mnt/ollama-cache
sudo mount -t tmpfs -o size=16G tmpfs /mnt/ollama-cache
Make the mount persistent across reboots:
echo "tmpfs /mnt/ollama-cache tmpfs size=16G 0 0" | sudo tee -a /etc/fstab
Adjusting Ollama Environment Variables
Configure Ollama to use the tmpfs mount and optimize memory handling. Create a systemd override:
sudo systemctl edit ollama
Add these environment variables:
[Service]
Environment="OLLAMA_MODELS=/mnt/ollama-cache"
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_NUM_GPU=1"
Restart the service:
sudo systemctl daemon-reload
sudo systemctl restart ollama
Verifying Configuration
Pull a test model to the new cache location:
ollama pull llama3.2:3b
Monitor disk I/O during the pull operation. You should see writes concentrated in RAM rather than your primary SSD. Check the cache directory:
ls -lh /mnt/ollama-cache
Caution: Verify tmpfs size matches your available RAM. Exceeding physical memory triggers swap usage, defeating the optimization. Test with smaller models first before deploying production workloads.
