Is Your Local LLM Spilling Out of VRAM? How to Check

You load a model, ask it something, and the answer crawls out one word at a time. The model "works," but it feels broken. Often the cause is simple: the model didn't fit in your GPU's memory, and part of it quietly moved into system RAM.

The good news is you don't have to guess. Both of the popular local runners will tell you exactly where the model landed, if you know where to look.

Check it in Ollama with one command

Load your model, send it a prompt, then open a second terminal and run:

ollama ps

Look at the PROCESSOR column. The Ollama FAQ spells out what it means:

  • 100% GPU means the whole model is in video memory. This is what you want.
  • 100% CPU means it is running entirely from system memory.
  • A split like 48%/52% CPU/GPU means part of the model is on the GPU and part is in system RAM.

That split is the one that catches people. The model still answers, so it's easy to miss. But every token now has to touch the slower memory too, and generation speed drops hard.

Why a model that "should fit" doesn't

Most people size a model by its download size. That's a start, but it leaves things out. The rough rule I use is:

VRAM (GB) = parameters in billions × bytes per parameter × 1.2 + 2

At Q4_K_M, bytes per parameter is about 0.5. So an 8B model works out to 8 × 0.5 × 1.2 + 2, about 6.8 GB. A 14B model is about 10.4 GB. A 32B model is about 21.2 GB. The 1.2 covers overhead and a short context, and the extra 2 GB is for the system and anything else using the card, like your desktop and browser.

Run that math for a 14B model on an 8 GB card and you can see the problem right away. It comes to about 10.4 GB, more than the card has, so part of the model ends up on the CPU.

The context window is the sneaky part

Context also costs memory, and it grows as you raise it. Ollama's FAQ says its default context window is 4096 tokens, and you can raise it with the OLLAMA_CONTEXT_LENGTH environment variable or the num_ctx parameter. Raise it a lot and a model that ran at 100% GPU yesterday can show a CPU/GPU split today, with no other change.

So if ollama ps shows a split right after you bumped the context, that's your answer. Drop it back down and check again.

In llama.cpp, the flag is -ngl

If you run llama.cpp's llama-server directly, the setting that controls this is -ngl (also written --n-gpu-layers). Per the server README it sets the maximum number of layers to keep in VRAM, and it takes an exact number, auto, or all. The default is auto, and the server also has a --fit option, on by default, that adjusts unset settings to fit in device memory. If you set a layer count by hand and the model spills, lower it, or let auto do the work.

What to do when it spills

You have three honest options, and none of them is magic:

  1. Pick a smaller quant. Going from Q8 to Q4_K_M roughly halves the weight memory. For most chat use that's the right trade.
  2. Pick a smaller model. A 14B that fits fully on the GPU will usually feel better than a 32B that half lives in system RAM.
  3. Shrink the context. If you don't need a huge window, don't pay for one.

And if none of those works for what you want to run, that's the real signal it's time for a card with more memory.

Before you buy anything, run the numbers for the exact model and context you have in mind. I keep the full tables in the how much VRAM do I need guide, and the VRAM calculator does the same math with a context add-on.

Sources: Ollama FAQ (docs.ollama.com/faq), llama.cpp server README (github.com/ggml-org/llama.cpp, tools/server). Memory figures are formula estimates, not benchmarks.

Comments

Popular posts from this blog

AMD RX 9070 XT for Local LLMs: ROCm Performance Guide (2026)

llama.cpp flash attention: how to enable and benchmark

SillyTavern with Local LLMs: Complete Setup for AI Companions