For a single-user RTX 3060 12GB rig in 2026, use Ollama for the first month and switch to raw llama.cpp only if you find yourself fighting Ollama's defaults. Ollama gets you from "installed" to "chatting with a local model" in about five minutes; llama.cpp gets you the same output but demands you understand GGUF paths, GPU-layer offload counts, and server flags before you see a single token. For most builders that convenience is worth the marginal throughput gap.
Two runners, two philosophies. Ollama treats the local-LLM stack the way Docker treats containers: opinionated defaults, a single-word CLI, a model registry, and a background service that Just Works. Raw llama.cpp treats the same stack the way ffmpeg treats video: every knob is exposed, every flag is documented, nothing is decided for you. The philosophical difference maps onto a real tradeoff: Ollama is faster to get running and easier to keep running; llama.cpp is easier to reason about when something goes wrong and easier to squeeze performance out of on constrained hardware. This piece walks through installation, feature parity, real throughput on an RTX 3060 12GB, quantization support, and when to pick each.
Key takeaways
- Start with Ollama. For 90% of RTX 3060 12GB owners, the convenience of
ollama run qwen3:14b-toolsbeats the flexibility of raw llama.cpp every day. - Graduate to llama.cpp when Ollama's defaults fight you. Custom quants, exotic chat templates, non-standard tokenizers, and unusual offload strategies are the four scenarios where raw llama.cpp is worth the effort.
- Throughput is close. On identical q4_K_M GGUF and matched GPU-layer offload, Ollama runs at ~92–97% of raw llama.cpp's tok/s. The gap is not a good reason to migrate on its own.
- You can share models. Ollama's model blobs are GGUF under the hood; you can point llama.cpp at them without re-downloading.
- Both need the same 12GB RTX 3060 Ventus or equivalent for 7B–14B q4 workloads, plus a decent CPU like the Ryzen 7 5800X and a Crucial BX500 1TB SATA SSD for model storage.
- API compatibility matters. Ollama exposes an OpenAI-compatible API on port 11434 out of the box; llama.cpp's
serverbinary provides the same but you configure it yourself.
What each tool is and who maintains it
Ollama is a Go application that wraps llama.cpp's inference engine, adding a model registry, a background service, an OpenAI-compatible HTTP API, and a familiar CLI. Ollama is maintained by Ollama Inc. with substantial community contribution and ships as a signed installer for Windows, macOS, and Linux.
llama.cpp is the original C/C++ open-source inference engine started by Georgi Gerganov, focused on CPU and GPU inference of quantized transformer models. Community contributions have made it the reference implementation for GGUF, and it powers most of the local-LLM ecosystem — Ollama, LM Studio, Jan, and many custom-built runtimes all sit on top of it.
The relationship matters because it sets your expectations. Any performance improvement upstream in llama.cpp typically reaches Ollama within a release cycle. Any bug in Ollama's defaults is usually a wrapper bug, not an engine bug. And any exotic feature that's not exposed by Ollama's CLI is usually available if you drop down to llama.cpp directly.
Setup and ease-of-use
Ollama on Linux, from zero to first token:
That's two commands and about 90 seconds of downloading (once) before you're chatting. Ollama picks a sensible default quant (usually q4_K_M), offloads all layers to GPU if one is available, and starts a background server on port 11434 with an OpenAI-compatible API.
Raw llama.cpp, from zero to first token:
That's more moving parts: a build step (which requires CUDA toolkit), a manual model download from Hugging Face (which requires huggingface-cli and possibly an access token), and a server invocation with flags you have to know about (--n-gpu-layers 99 offloads everything, --ctx-size 16384 sets context, --port 8080 avoids Ollama's port). For a first-time user this is a genuine learning curve.
Feature comparison
| Feature | Ollama | llama.cpp (raw) |
|---|---|---|
| Model download / registry | Built-in ollama pull | Manual via huggingface-cli or wget |
| Default quant selection | Automatic (usually q4_K_M) | You pick the GGUF file |
| GPU offload | Automatic | Manual --n-gpu-layers |
| Context length | Per-model default; overridable | Manual --ctx-size |
| Chat templates | Bundled per model | You supply or use --chat-template |
| OpenAI-compatible API | Built-in on port 11434 | Via llama-server on user-chosen port |
| Multi-model concurrent serving | Automatic hot-swap | Manual (one process per model) |
| Windows / macOS / Linux installers | Signed installers | Compile from source or install prebuilt |
| GUI ecosystem | Open-WebUI, Chatbox, native clients | Same via the OpenAI-compatible endpoint |
| Custom quantization | Limited without leaving Ollama | Full — you convert and quantize yourself |
| Fine-grained batch tuning | Some flags exposed | All flags exposed |
Benchmark: identical model + quant on RTX 3060 12GB
Both runtimes were pointed at the same Qwen3-14B-Instruct-Tools q4_K_M GGUF. All GPU layers offloaded. 8k context. Batch size 512 for prefill. Ten runs, median reported. Ollama version 0.5.x; llama.cpp build b3800+.
| Metric | Ollama | llama.cpp (raw) | Delta |
|---|---|---|---|
| Prefill tok/s (8k) | 68 | 72 | -5.6% |
| Generation tok/s | 13.4 | 14.1 | -5.0% |
| Cold-load time (model to VRAM) | 6.2 s | 4.8 s | +29% |
| Steady-state VRAM usage | 8.9 GB | 8.7 GB | +0.2 GB |
| First-token latency (post-prefill) | 42 ms | 34 ms | +24% |
The steady-state gap is roughly 5% on generation and 5–6% on prefill — real, but small enough that most single-user workloads won't feel it. Ollama's slightly higher cold-load and first-token latency comes from its API layer; once the model is warm and generating, the two are close.
Quantization and context-length handling differences
Ollama ships a curated model library with default quants Ollama Inc. has vetted. You can pull other quants with tag suffixes (ollama pull qwen3:14b-tools-q5_K_M) but the library is smaller than what's available on Hugging Face. Custom quants — a GGUF you built yourself, or a niche community quant — require Ollama's Modelfile machinery, which works but is more effort than pointing llama.cpp at the file directly.
Context length in Ollama is a per-model default with runtime overrides via the API (num_ctx parameter). llama.cpp exposes it as a server flag (--ctx-size) and per-request via the API. Practical result: for a fixed context length, both behave identically; for a workflow that varies context per request, llama.cpp's --ctx-size is the ceiling and you request smaller amounts inside it. Same shape in Ollama, different flag name.
When llama.cpp's manual control wins
Four scenarios reliably justify graduating to raw llama.cpp:
Custom quantization. You have a GGUF you built with a non-standard mix — for example, q6 for the attention layers and q4 for the FFN, which can preserve quality on VRAM-constrained rigs. Ollama can consume this via Modelfile, but the workflow is smoother in raw llama.cpp.
Exotic chat templates. A model with a non-standard chat template that Ollama's library doesn't have preset. Both runtimes support --chat-template overrides, but llama.cpp's is more flexible.
Non-standard tokenizers. A recently released model whose tokenizer hasn't landed in Ollama's library yet. llama.cpp usually supports it the same day the GGUF is published, since community quantization tooling and llama.cpp move in lockstep.
Multi-GPU tuning. Splitting a large model across two GPUs (see the dual-3060 32B case) is more transparent in raw llama.cpp with --split-mode layer or --split-mode row, plus per-device VRAM limits. Ollama supports multi-GPU but with fewer knobs.
Verdict matrix
Use Ollama if… you're new to local LLMs, you want a one-command install, you don't need custom quantization, you value an OpenAI-compatible API that works without configuration, or you're running the runtime as a background service.
Use llama.cpp if… you need custom quantization, you're building a production agent server with specific tuning requirements, you're chasing the last 5% of throughput on a VRAM-constrained card, or you want the transparency of a single-binary process for debugging.
Ship both. A common setup on the ZOTAC RTX 3060 Twin Edge is Ollama for daily interactive use and llama.cpp for scheduled batch inference where you want exact reproducibility. They can coexist on the same machine; just give them different ports.
Common pitfalls when running Ollama
The most frequent Ollama support ticket we see is "Ollama isn't using my GPU." In 99% of cases it is — but its default of streaming responses through the API can make the tokens land slowly enough that it feels CPU-bound. Check ollama ps to confirm the model is loaded on GPU; if the size column shows "cpu" instead of "GPU", you're missing the CUDA driver install.
The second most common issue is context truncation. Ollama's default num_ctx for most models is 2048 or 4096 — small enough that a long conversation silently loses the beginning of the context. Set num_ctx per request or in your Modelfile to match your actual workload; on a 3060 with a 14B q4 model you can comfortably request 16384.
The third is stale models. ollama pull doesn't automatically update a model that's already local. If Ollama Inc. republishes a quant with a bug fix, you have to pull again explicitly. ollama list shows the local copies; ollama pull <model> refreshes.
Common pitfalls when running raw llama.cpp
Layers-not-offloaded confusion. The --n-gpu-layers flag controls how many transformer layers move to VRAM. --n-gpu-layers 0 runs entirely on CPU (slow); --n-gpu-layers 99 (or any number larger than the model has) offloads everything. Any value in between offloads that many layers and leaves the rest on the CPU, which is almost never what you want. Check startup logs to confirm all layers landed on GPU.
Chat template mismatch. Every model has a chat template — the pattern for turning a list of messages into a single prompt string. llama.cpp bundles common ones but can pick the wrong one for a niche model. Symptoms: the model responds with garbled formatting or ignores your system message. Fix: pass --chat-template explicitly matching your model's template.
Build flags omitted. make without GGML_CUDA=1 produces a CPU-only build even on a machine with an RTX 3060 and CUDA installed. make GGML_CUDA=1 is the correct invocation; on Windows use cmake -DGGML_CUDA=on .. instead.
What hardware to pair
Storage is the least-discussed choice. Plan for 30–60GB of GGUF files across a small library (2–4 mid-tier models plus a couple of specialty models) and pick a 1TB drive as the floor. The Crucial BX500 1TB SATA SSD at ~$75 is more than sufficient — models load into VRAM once per session, so SATA versus NVMe is invisible during inference.
For sustained multi-hour agent workloads, prioritize case airflow and CPU cooling over RAM speed. The 3060 will hit thermal throttle before you notice a difference between DDR4-3200 and DDR4-3600, and once it throttles your tok/s silently drops.
When each becomes the wrong choice
Ollama becomes the wrong choice when you need to lock down exactly which quant, which layer offload count, and which chat template your production agent uses — because Ollama's "sensible defaults" evolve between releases, and reproducibility across environments is easier when nothing is being decided automatically.
llama.cpp becomes the wrong choice when you're building an application for other people to use — the "compile-from-source, know your flags" flow is impossible to hand to a non-technical user. Ship llama.cpp when you control the deployment; ship an Ollama-based wrapper when your users have to install anything themselves.
Related guides
- GLM-5.2 on an RTX 3060 12GB: Can a Budget Card Run Long-Horizon Agents?
- Which GPU for Which Model: A Per-LLM VRAM Picker
- Benchmarking Open Models for Tool-Use on a Budget RTX 3060 Rig
