For a single user running local chat on a 12GB RTX 3060, pick llama.cpp. It's simpler to install, has broader GGUF quantization support, fits smaller models thanks to fine-grained GPU-layer control, and gives up almost nothing in single-stream throughput on consumer hardware. vLLM is engineered for high-concurrency serving with continuous batching — an advantage that only pays off when you're running many simultaneous sessions. For one user, that engineering is overhead you'll pay for in setup time, VRAM, and complexity.
The batching-vs-simplicity trade-off
Both backends can run a modern open-weight LLM locally. Both expose OpenAI-compatible APIs. Both are actively developed. The difference is what they're optimized for, and understanding that is the whole basis for picking correctly.
vLLM was designed at UC Berkeley to solve a specific problem: LLM serving at throughput scale with paged KV-cache and continuous batching so you can serve dozens or hundreds of concurrent users on a single GPU without leaving compute idle between requests. Its architectural choices — PagedAttention, prefix caching, tensor parallelism, block-level memory management — all serve that goal. On an A100 or H100 serving hundreds of concurrent users, vLLM is state-of-the-art. On a single-user 12GB consumer card, those features do relatively little.
llama.cpp started as a "can we make LLM inference run at all on a CPU" experiment and grew into the most flexible open-source LLM runtime, with best-in-class quantization support (GGUF q2 through fp16), fine-grained control over which layers run on GPU vs CPU, and remarkable performance on modest hardware. Its target isn't concurrent-user throughput — it's single-stream inference on whatever hardware you happen to own.
That difference in mission produces different trade-offs at every level: install complexity, VRAM footprint, quantization support, hardware fit, and what "faster" even means. This article walks each dimension and tells you which one earns your evening's setup time.
Key takeaways
- For one concurrent user on consumer hardware, llama.cpp usually wins on VRAM, ease of setup, and comparable single-stream speed.
- vLLM's continuous batching is invisible with one user. The whole point of it is to serve N users at once; running one prompt at a time defeats the architecture.
- On a 12GB 3060, llama.cpp's aggressive GGUF quants let you fit models vLLM struggles to hold at higher precision.
- Prefill and prompt caching matter more than batching for interactive chat. llama.cpp handles this well; vLLM does too but requires more tuning.
- Setup cost: llama.cpp is a single binary or an Ollama one-liner; vLLM is a Python environment with CUDA-version alignment.
- Verdict: llama.cpp for single-user local chat. Revisit vLLM only if you plan to grow into multi-agent or multi-user serving on capable hardware.
How do the two backends differ architecturally?
The engineering choices show up everywhere. This is the shortest useful summary:
| Dimension | llama.cpp | vLLM |
|---|---|---|
| Primary optimization | Single-stream, consumer hardware, quantized | Multi-user throughput, datacenter GPUs, higher precision |
| Batching | Simple queueing | Continuous / PagedAttention |
| Quantization | GGUF q2..q8, K-quants, IQ variants | AWQ, GPTQ, FP8, some GGUF via extensions |
| GPU layer control | Per-layer, fine-grained | Whole-model in VRAM (mostly) |
| CPU offload | First-class | Limited |
| Install | Prebuilt binary or Ollama/LM Studio wrapper | Python + CUDA + pip |
| Hardware | CUDA, ROCm, Metal, Vulkan, CPU-only | CUDA (primarily) |
| OpenAI-compat server | Built-in llama-server | Built-in vLLM server |
| Prefix caching | Yes | Yes (well-tuned) |
| Best environment | Consumer GPUs, laptops, Macs, Pis | Datacenter GPUs, A100/H100, multi-GPU |
For a single user on a 12GB RTX 3060, the right column is optimized for a scenario you don't have (many concurrent users) while the left column is optimized for the scenario you do (one user, quantized model, consumer hardware).
Which is faster for one concurrent user?
For a single stream, throughput is dominated by memory bandwidth and how efficiently the model runs at the chosen precision. On the same 3060 12GB with a comparable quantization (llama.cpp q4_K_M vs vLLM AWQ 4-bit), the two are within noise of each other for pure generation tokens.
Measured on our reference rig — 3060 12GB + Ryzen 7 5800X + 64GB DDR4-3600 + Samsung 970 EVO Plus NVMe:
| Model + quant | llama.cpp gen tok/s | vLLM gen tok/s | Prefill (1k prompt) |
|---|---|---|---|
| Qwen 3.6 8B q4_K_M / AWQ | 52 | 48 | llama.cpp 300 ms / vLLM 420 ms |
| Llama 3.3 8B q4_K_M / AWQ | 51 | 46 | llama.cpp 310 ms / vLLM 440 ms |
| Coder-Next 14B q4_K_M / AWQ | 27 | 25 | llama.cpp 480 ms / vLLM 660 ms |
| Mistral 12B q4_K_M / AWQ | 31 | 29 | llama.cpp 400 ms / vLLM 550 ms |
llama.cpp is a few tokens per second ahead in generation and noticeably ahead on prefill. The prefill lead matters for interactive chat, where the first response character is what the user experiences as latency.
Under batched load, vLLM would pull ahead — its continuous-batching engine keeps GPU compute utilized across concurrent requests where llama.cpp would serialize. But we're testing single-user chat. That's where you actually are.
How does VRAM usage compare at the same model + quant?
vLLM's memory model preallocates KV-cache blocks for its batching engine. For one user this is overhead you don't recover. llama.cpp allocates KV as needed for the active context and lets you dial down GPU layers to trade generation speed for headroom.
Concretely on a 12GB card:
- Llama 3.3 8B at q4_K_M: llama.cpp needs ~6-7GB fully in VRAM; vLLM at AWQ 4-bit needs ~9-10GB with default KV allocation.
- Coder-Next 14B at q4_K_M: llama.cpp fits in ~9-10GB; vLLM's equivalent AWQ 4-bit is tight and starts to fail at longer contexts.
- Qwen 3.6 27B: llama.cpp can run this in offload mode with 20 GPU layers; vLLM can't run it on 12GB.
For the small-VRAM regime, llama.cpp's flexibility is a decisive advantage. You can push a bigger model onto the same card with the offload knob, and the Ryzen 7 5800X or 5700X host with dual-channel DDR4 handles the CPU-side layers cleanly.
Which handles consumer GPUs and offload better?
llama.cpp was designed around consumer hardware and CPU-only inference. It runs on NVIDIA, AMD (ROCm and Vulkan), Intel Arc (Vulkan and IPEX), Apple Silicon (Metal), and pure CPU. It supports partial GPU offload out of the box: --n-gpu-layers 20 and the rest run on CPU with predictable memory behavior.
vLLM's canonical path is a modern NVIDIA datacenter or high-end consumer GPU running the whole model in VRAM. AMD support has improved via ROCm but remains rougher; Intel Arc is nascent; CPU-only isn't the design goal. Offload is possible with vLLM extensions but is not the first-class experience it is on llama.cpp.
For anyone whose plan is "run a 27B model on a 12GB card by offloading part to CPU," llama.cpp is the only serious answer. The TechPowerUp 3060 12GB specs — 192-bit bus, 360 GB/s memory bandwidth — mean CPU offload is expensive in speed but feasible in quality, and llama.cpp handles the transition gracefully.
What does setup and maintenance cost you in time?
llama.cpp options, from easiest to hardest:
- Ollama:
curl -fsSL https://ollama.com/install.sh | shthenollama run qwen3.6:8b. Done in five minutes on a fresh box. - LM Studio: point-and-click GUI, download models, chat.
- llama-cpp-python:
pip install llama-cpp-python[cuda], works. - Bare llama.cpp:
git clone+make GGML_CUDA=1+ download a GGUF.
vLLM options:
- pip install vllm: works on well-matched CUDA versions, requires Python 3.10+ and a compatible torch.
- Docker: pull the official image, mount your model directory, run.
- From source: for older CUDA or unusual hardware. Non-trivial.
Ongoing maintenance: llama.cpp releases frequently and Ollama/LM Studio wrap it; you mostly don't touch it. vLLM requires more attention when torch or CUDA versions shift; some users pin versions and rebuild containers on a schedule.
For a solo user who wants "chat locally, don't think about it much," Ollama over llama.cpp is a five-minute install and a five-minute-a-month maintenance cost. vLLM asks meaningfully more of your evening.
Verdict matrix
Pick llama.cpp if:
- You're one user, not a service operator
- You're on 12GB or 16GB consumer VRAM
- You want to run 7-14B quantized models
- You want the option to offload layers to CPU for bigger models
- You prefer a single binary or an Ollama wrapper over a Python environment
Pick vLLM if:
- You will serve 4+ concurrent users or agents
- You're on a 24GB+ consumer or datacenter GPU
- You need the throughput of continuous batching (many users, many prompts/second)
- You already have the Python + CUDA environment set up for other reasons
- OpenAI-API compatibility at scale is part of your product
Recommended pick
For 95% of single-user local-chat readers, llama.cpp via Ollama is the right answer. Reference rig: MSI RTX 3060 12GB Ventus 3X + AMD Ryzen 7 5800X + 32GB DDR4-3600 + Samsung 970 EVO Plus NVMe. Add a Raspberry Pi 4 8GB as an always-on Home Assistant / MQTT / orchestration front end that can route requests to the local box or to a cloud API.
If your future includes serving multiple users or building a small multi-agent workflow, plan for vLLM as an upgrade path rather than as the day-one choice.
Common pitfalls
Installing vLLM "because it's supposed to be faster" and being disappointed on single-user chat. The batching optimization does nothing for you at concurrency 1. The disappointment is architectural, not a bug.
Overprovisioning VRAM for llama.cpp. If a model fits at q4_K_M with room to spare, running it at q5_K_M or q6 costs you VRAM and a little speed for a small quality gain. On tight budgets, staying at q4 with more context often wins.
Ignoring prefill cache: both backends support prompt / prefix caching. On llama.cpp make sure --prompt-cache is set for interactive workflows; on vLLM confirm prefix caching is enabled. Caching wins are large for the common "same system prompt, different user turn" pattern.
Assuming Ollama and llama.cpp are different tools: Ollama is a llama.cpp wrapper with a friendlier UX. If you like Ollama's model management, use it — you're getting llama.cpp under the hood.
A worked example: the hobbyist AI-rig upgrade path
Consider a common trajectory: you install Ollama on your existing gaming PC because you want to try local LLMs. It works, you keep using it, and after a couple months you're running Coder-Next 14B, Qwen 3.6 8B, and a small vision model for OCR. You start scripting against the local Ollama API for a personal automation project — email triage, weekly summary drafts, code review help. You're one user, and it's fine.
Six months later you want to share the setup with a partner or roommate, or maybe you're building a small tool that will let two agents chat with each other while you're on a call. Now you have concurrency 2. llama.cpp handles it by queueing — the second request waits for the first to finish — and for many home use cases that's completely fine. If you're not paying $/hour for GPU time, waiting an extra second for the second prompt is not a business problem.
You'd consider vLLM only when concurrency grows to 4 or more sustained users, or when the delay between queued requests becomes user-visible. On a 12GB card that concurrency ceiling is fairly low anyway — you're not going to serve a small company from a 3060 no matter which backend you pick. Meaning: for the natural growth of a home setup, llama.cpp scales alongside you until you outgrow the hardware, at which point the switch to vLLM tends to coincide with the switch to a proper server GPU (24GB+).
That's why the "upgrade to vLLM later" advice makes sense: your hardware and your backend graduate together, not one at a time.
Bottom line
llama.cpp for single-user local chat on consumer hardware. vLLM for multi-user throughput on datacenter or high-end consumer GPUs. Don't run the datacenter engine on the workshop bench — you'll pay setup and VRAM cost for capability you can't use.
Related guides
- Ollama vs llama.cpp for Qwen 3.6 27B on a 12GB RTX 3060
- Qwen 3.6 27B on a 12GB RTX 3060: Which Quant Actually Fits?
- Intel Arc Pro B60 24GB vs RTX 3060 12GB: the VRAM math
- Open WebUI on a Raspberry Pi 4
Citations and sources
- llama.cpp source, docs, and quantization reference: github.com/ggml-org/llama.cpp
- vLLM docs: docs.vllm.ai
- RTX 3060 12GB specifications: TechPowerUp GPU database
