**VRAM & Offloading**
- [ ] Verify model + KV cache fits entirely in VRAM. Overflow forces CPU swap → prefill collapses.
- [ ] Set `-ngl` to fully offload (e.g., `-ngl 999`). Partial offloading causes CPU↔GPU transfer bottlenecks during prefill.
- [ ] Enable `--flash-attn` if your GPU/arch supports it (cuts memory bandwidth pressure during prefill).

**Context & Batch**
- [ ] Reduce context length (`-c`). Prefill scales poorly with large contexts; test with `-c 2048` to isolate.
- [ ] Increase upload batch size (`-ub 2048` or higher) to feed more tokens per GPU kernel launch.
- [ ] Ensure KV cache stays on GPU (avoid `--no-kv-offload` or similar flags).

**Threading & Sync**
- [ ] Lower CPU threads (`-t 1` or `-t 2`). Excessive CPU threads create sync overhead when GPU is the bottleneck.
- [ ] Check logs for "offloading to CPU" or "fallback" warnings; fix VRAM limits if present.

**Model & Quantization**
- [ ] Use GPU-optimized GGUF quants (Q4_K_M, Q5_K_M, Q8_0). Avoid exotic quants with CPU-only ops.
- [ ] Verify architecture compatibility; some newer models lack full GPU kernel coverage in llama.cpp.

**Quick Diagnostics**
- [ ] Run with `-v` to confirm prefill vs decode tokens/sec.
- [ ] Test with a short prompt + small context to establish a healthy baseline.
- [ ] Monitor GPU memory bandwidth during prefill (should be near saturation if healthy).

*Note: Prefill should typically report higher tokens/sec than decode. If it's lower, you're hitting a VRAM overflow, CPU-GPU sync, or bandwidth bottleneck.*