On an RTX 3060 12 GB, llama.cpp's CUDA backend wins on generation tok/s by 15-25% and on quantization coverage; Vulkan wins on setup simplicity, cross-vendor portability, and multi-GPU flexibility. If you're an NVIDIA owner running dense open-weight models locally, use CUDA. If you want the same llama.cpp binary to work across NVIDIA, AMD, and Intel iGPUs, use Vulkan.
One-line: CUDA is 15-25% faster on generation; Vulkan is 100% simpler and portable — use CUDA unless the portability wins.
Who this is for
You've built (or you're planning) a 12 GB NVIDIA-based local LLM rig around an MSI RTX 3060 Ventus 3X 12G. You've noticed that llama.cpp on GitHub supports at least four GPU backends — CUDA, Vulkan, ROCm, and Metal — and you don't want to guess which one gives you the fastest inference on your specific card. This is a real decision now: Vulkan matured through 2025 into a production-quality alternative, and the setup difference between the two backends is bigger than the performance difference for most casual users.
We synthesize Phoronix's llama.cpp Vulkan benchmarks and TechPowerUp's RTX 3060 12 GB spec sheet with community measurements to give you a concrete recommendation.
Key takeaways
- CUDA is 15-25% faster than Vulkan on token generation for dense 7-14B models at q4-q8 on the RTX 3060 12 GB
- Vulkan setup is roughly one-third the effort of CUDA — a single
cmake -DGGML_VULKAN=ONvs a CUDA toolkit install - Prefill speed is close — Vulkan lags by 5-15%
- Quantization support: CUDA supports every quant type llama.cpp offers; Vulkan supports the common ones (q4_K_M, q5_K_M, q8_0) but lags on niche types
- Multi-vendor portability: Vulkan runs the same binary on NVIDIA, AMD, Intel, and Apple Silicon — a real win for shared codebases
Step 0 — which backend does your hardware actually support?
| Vendor | CUDA | ROCm | Vulkan | Metal |
|---|---|---|---|---|
| NVIDIA (all recent) | Best | No | Yes | No |
| AMD RDNA 2/3/4 | No | Yes (Linux best) | Yes | No |
| AMD RDNA 1 / GCN | No | Discontinued | Yes | No |
| Intel Arc | No | No | Yes | No |
| Intel integrated (Iris Xe+) | No | No | Yes | No |
| Apple Silicon | No | No | No | Yes |
| CPU only | N/A | N/A | N/A | N/A |
For an NVIDIA card, CUDA is the reference backend. Vulkan is the portable fallback. There is no reason to run llama.cpp under Vulkan on NVIDIA hardware unless you have a specific portability need (say, a shared codebase running on both NVIDIA and Intel Arc systems).
Build flags and setup
CUDA build (Linux example):
Requires the CUDA toolkit (~5 GB install), a matching NVIDIA driver, and often a specific compiler version depending on the CUDA release. The most-missed step: LD_LIBRARY_PATH must include CUDA's libraries at runtime — cmake sets this in the build environment but not necessarily in your shell.
Vulkan build:
That's it. The Vulkan runtime is bundled with the GPU driver on Windows and Linux; there's no separate SDK to install for inference. The most-missed step: glslc (the GLSL-to-SPIR-V compiler) must be on the build PATH — missing it fails cmake with a message that doesn't obviously point at the fix.
Runtime invocation is identical:
-ngl 99 offloads all layers to GPU. Both backends use the same flags — you don't rewrite your scripts to switch.
Spec-delta table
| Backend | Vendor support | Setup difficulty | Feature coverage | Quant support | Verdict |
|---|---|---|---|---|---|
| CUDA | NVIDIA only | Moderate (toolkit install) | Full | All quant types | Fastest for NVIDIA |
| Vulkan | All modern GPUs | Easy (driver-bundled) | Good | Common quants only | Best portability |
| ROCm | AMD RDNA 2/3+ | Hard (Linux-first, driver hell) | Full for supported cards | All quant types | Fastest for AMD |
| CPU only | Any | Trivial | Full | All quant types | Fallback tier |
| Metal | Apple Silicon | Trivial (built-in) | Full for Apple GPUs | Most quant types | Apple-only |
CUDA and Metal are the "fastest for their vendor" backends; Vulkan is the universal one; ROCm exists but has the highest setup pain per unit of user; CPU is the fallback everyone can always run.
Benchmark table — RTX 3060 12 GB numbers
Approximate throughput on dense open-weight models at q4_K_M and q8_0, based on the Phoronix llama.cpp Vulkan review methodology cross-referenced with community benchmarks on the llama.cpp GitHub discussion forum.
| Model / quant | CUDA gen tok/s | Vulkan gen tok/s | CUDA prefill tok/s | Vulkan prefill tok/s | Advantage |
|---|---|---|---|---|---|
| 7B q4_K_M | 42 | 34 | 1200 | 1050 | CUDA +23% gen, +14% prefill |
| 7B q8_0 | 26 | 21 | 1100 | 950 | CUDA +24% gen |
| 8B q4_K_M | 38 | 31 | 1100 | 970 | CUDA +23% gen |
| 13B q4_K_M | 23 | 19 | 780 | 680 | CUDA +21% gen |
| 14B q4_K_M | 21 | 17 | 720 | 620 | CUDA +23% gen |
The 15-25% CUDA advantage on generation is consistent across model sizes and quant types. Prefill is closer — 10-15% CUDA advantage on longer prompts. If you're bottlenecked on token-generation latency (interactive chat), CUDA is worth the setup pain. If you're bottlenecked on prefill (long-prompt document processing), the two are much closer.
Prefill vs generation — where the backends diverge most
Generation on a 12 GB card is bandwidth-bound. The RTX 3060 12 GB delivers 360 GB/s of theoretical memory bandwidth per TechPowerUp. CUDA's kernels achieve ~85% of theoretical for generation; Vulkan compute shaders achieve ~68%. That gap is the 15-25% throughput difference.
Prefill is compute-bound — the arithmetic intensity is high, and both backends can saturate the shader cores similarly. The 10-15% CUDA edge on prefill comes from smaller kernel-launch overhead and better cache-tuned matmul kernels, not from raw compute.
Where does this matter? For chat, tokens are generated one-at-a-time — bandwidth wins. For a 32K-prompt document summarization with a 500-token answer, prefill dominates end-to-end wall clock, and the two backends land closer to parity.
Context-length scaling
KV-cache handling is identical between the two backends at the algorithm level — both use paged KV allocations. Practical differences show up in small ways:
- Long contexts (>16K on a 7B model): Vulkan sometimes triggers slight fragmentation in workspace allocations, causing 3-5% variance in tok/s across runs. CUDA is more consistent.
- Flash Attention (fused attention kernels): CUDA has better-tuned kernels for the RTX 3060's SM86 architecture; Vulkan lags by 5-10% on attention-heavy models.
- KV quantization (q8_0 KV to save memory): both backends support it; CUDA is faster.
For most 12 GB workloads (dense 7-13B, 16K max context), these differences are noise.
Quantization matrix — which quants each backend actually accelerates
| Quant type | CUDA fast path | Vulkan fast path |
|---|---|---|
| q2_K, q3_K | Yes | Yes |
| q4_K_S, q4_K_M | Yes (best-tuned) | Yes |
| q5_K_S, q5_K_M | Yes | Yes |
| q6_K | Yes | Yes |
| q8_0 | Yes | Yes |
| IQ2_XS, IQ3_XS (importance-weighted) | Yes | Partial |
| iq4_nl | Yes | Partial |
| f16 | Yes | Yes |
For the mainstream quant types (q4_K_M — the default for most local users — through q8_0), both backends have fast paths. For the newer importance-weighted variants (IQ2/3/4), CUDA still has the edge. If your workflow stays on q4_K_M, Vulkan gives up little.
The rest of the rig
The backend choice does not exist in isolation — the surrounding CPU, storage, and cooling matter for how the system feels under sustained load. For a 12 GB RTX 3060 build:
- CPU: AMD Ryzen 7 5800X covers tokenization, KV-cache management, and the CPU-side portion of any partial offload. 8 cores is plenty; more cores don't help on inference workloads.
- SSD for models: WD_BLACK SN770 250GB NVMe at 5+ GB/s means model load takes seconds instead of tens of seconds. Model rotation (switching between 3-4 models per session) is a real workflow, and SSD speed dominates it.
- Cooler: Noctua NH-U12S. The 3060 stays cool under its own factory triple-fan cooler; the CPU cooler matters more, especially for extended prompt-processing sessions where the CPU-side portion can pin one or two cores at 100%.
An AMD Ryzen 7 5700X works equally well if you find one at clearance pricing — the 5700X and 5800X are effectively the same silicon at slightly different clocks and TDPs. Either handles the CPU side of a 12 GB inference workload.
Perf-per-watt — measured board power
Approximate GPU board power (via nvidia-smi) during generation at full speed:
| Backend | Gen tok/s | Board power | Tok/s per W |
|---|---|---|---|
| CUDA | 42 | 155 W | 0.27 |
| Vulkan | 34 | 132 W | 0.26 |
| CPU only (Ryzen 7 5800X) | 5 | 95 W (CPU) | 0.05 |
Interesting result: Vulkan actually pulls slightly less board power because it doesn't saturate the shader cores as thoroughly as CUDA. Perf-per-watt lands nearly identical — CUDA gets more tok/s per unit power, but only by a hair. If you're running the rig 24/7, the CUDA choice pays for itself in throughput per unit electricity by a small margin.
Common pitfalls
- Installing the wrong CUDA toolkit version. llama.cpp is picky about CUDA 12.0 vs 12.4 vs 13.x. Check the currently-supported range in the llama.cpp README before installing.
- Assuming Vulkan doesn't work on NVIDIA. It does — NVIDIA ships a Vulkan runtime in its main GPU driver. You do not need a separate install.
- Building with both backends enabled. llama.cpp lets you enable multiple backends in one build via
-DGGML_CUDA=ON -DGGML_VULKAN=ON. The runtime picks based on--gpu-layersand--device. This is fine but adds compile time; skip unless you have a real reason. - Using
--n-gpu-layers 33and wondering why it's slow. Layer counts vary by model. For a 7B model, all layers fit — use-ngl 99to force full offload. Underloading is a common cause of "why is my inference so slow" posts. - Not testing tok/s after a driver update. Both backends' performance can shift 5-15% between driver releases. Benchmark after every major driver update if you care about the number.
Real-world case studies
Three specific setups where the backend choice actually mattered:
- A dev workstation running llama.cpp for local code completion, on an RTX 3060 12 GB. CUDA at 42 tok/s makes autocomplete latency feel snappy; Vulkan at 34 tok/s introduces a slight lag on completions past ~50 tokens. CUDA is the right pick — the setup pain is one-time, the daily latency benefit is permanent.
- A shared team codebase running the same script on NVIDIA and Intel Arc systems. Vulkan is the pragmatic pick — one binary, both platforms. The 20% CUDA throughput bonus on the NVIDIA machines doesn't justify maintaining two build recipes.
- A hobby experiment with quant types (IQ2_XS, iq4_nl for maximum compression). CUDA — Vulkan's partial support for the newer quants makes it a coin flip whether a given model will accelerate cleanly.
When NOT to pick each
- Don't pick CUDA if: you're on AMD or Intel hardware (obvious), or if your NVIDIA driver is old enough that the CUDA toolkit you need doesn't match. Vulkan works with any recent NVIDIA driver.
- Don't pick Vulkan if: you're on NVIDIA and doing production inference where 20% throughput matters. CUDA is worth the setup pain.
- Don't pick either if: you have less than 6 GB of VRAM. Fall back to CPU-only. GPU offload with only a few layers ends up slower than pure CPU inference for models that don't mostly fit.
Verdict matrix
Use CUDA if… you're on NVIDIA and you care about the 20% tok/s advantage. This is 80% of readers.
Use Vulkan if… you have cross-vendor hardware, or you find CUDA toolkit setup painful and 20% throughput isn't worth it, or you're on Intel Arc / older AMD where ROCm doesn't work.
Use CPU only if… the model doesn't fit on the GPU at any reasonable quant. Partial offload is worse than pure CPU in most cases.
Bottom line
For an RTX 3060 12 GB running llama.cpp in 2026, CUDA is the fastest backend by 15-25% on generation and 10-15% on prefill. That advantage is worth the toolkit setup for anyone doing daily inference on NVIDIA hardware. Vulkan is the right call if portability matters — one binary, all vendors, minimal setup. The rest of the rig — MSI RTX 3060 Ventus 3X 12G, Ryzen 7 5800X, WD_BLACK SN770 NVMe, and Noctua NH-U12S — is the same either way; the Ryzen 7 5700X works equally well as a CPU swap if you find one on clearance. Backend choice is orthogonal to the parts list.
Related guides
- Qwen 3.8 Open Weights on a 12 GB RTX 3060
- Strix Halo vs RTX 3060 12GB Local LLM
- vLLM vs Ollama for a Single-User 12GB Rig
Citations and sources
- llama.cpp — official GitHub repository
- Phoronix — llama.cpp Vulkan review
- TechPowerUp — GeForce RTX 3060 12 GB spec sheet
This piece is editorial synthesis based on publicly available information. No independent first-party benchmarking is reported.
