· Comparison · 3 min read

Ollama vs llama.cpp vs llamay: picking a local inference server

Three ways to serve a GGUF file on your own hardware, what each one is actually optimising for, and the one capability only one of them has.

All three run the same GGUF files. They differ in what they think the hard problem is.

The short version

Ollamallama.cppllamay
Optimises forGetting startedRaw controlReusing computed state
InstallOne installerBuild, or a binaryOne static binary
DependenciesNone visibleDepends on buildNone
APIIts own + OpenAIIts own + OpenAIOpenAI, Anthropic, Ollama
Model storeIts ownFiles you manageIts own, and reads Ollama’s
Structured outputFormat flagGBNF grammarsSchema enforced while sampling
Fork a warm contextYes
Snapshot to a fileYes

Ollama

The one to pick if you want a model answering in two minutes and do not want to think about any of this. ollama run llama3.2 and you are done. The model library is curated, the defaults are sensible, and it hides the file layer completely.

What you give up is that hiding. When you want a specific quantisation of a specific file, or to know why something is slow, the abstraction is in the way.

llama.cpp

The reference implementation and the thing the others are measured against. Every knob is exposed, new architectures land here first, and if you want to understand exactly what your hardware is doing this is where you look.

The cost is that it is a toolkit rather than a product. You will build it, you will read the flags, and you will keep a note of which ones you used.

llamay

Same files, same quantisations, and it reads Ollama’s store, so switching costs no downloads. The API surface is wider — it serves OpenAI, Anthropic and Ollama shapes natively, so a client written for any of them works unchanged.

What it has that the other two do not is a state engine. A conversation’s key-value cache is a first-class object:

# Build an expensive context once
ID=$(curl -s -X POST localhost:11435/v1/contexts \
      -H 'content-type: application/json' \
      -d "{\"prompt\": $(jq -Rs . < handbook.txt)}" | jq -r .id)

# Fork it per request — a page-table copy, not a memory copy
curl -s -X POST "localhost:11435/v1/contexts/$ID/fork?n=8"

# Or write it to a file and restore it on another machine
curl -s "localhost:11435/v1/contexts/$ID/snapshot" > handbook.ctx

That matters for one shape in particular: a large shared prefix and many short completions against it. A corpus, a codebase, a manual, a long instruction. Every request otherwise re-reads the whole prefix, and on a 4,000-token instruction that re-read is the workload.

So which

Ollama if you want to stop reading now and have something working.

llama.cpp if you are optimising a specific model on specific hardware and want every knob.

llamay if you are building a product on top: many requests sharing a prompt, structured output you need to be structured, or contexts that have to survive a process.

They are not exclusive. llamay reads Ollama’s store, so you can run both and point one client at each — different ports, same weights, same machine.

What is the same

All three run GGUF, all three take the same quantisations, and all three keep your data on your hardware. That last one is the reason most people are reading this page, and none of the three differ on it.