Open-Weight LLMs on Windows: When a Quantized Local Model Is a Credible Production Choice
For privacy-bound and cost-sensitive work, a well-quantized open-weight model on an ordinary Windows machine is now a serious option. The model you download matters less than the bits you store it in and the memory budget you fit it into. Here is the evidence, the arithmetic and the setup.
You can now run a capable AI model on an ordinary Windows computer for real work, especially when data must stay private, as long as you shrink it the right amount and make sure it actually fits in memory.
Thesis
For privacy-bound or cost-sensitive workloads, a well-quantized open-weight model on ordinary Windows hardware is now a credible production option — and success depends less on which model you pick than on the quantization and memory budget you fit it into.
Key takeaways
- Local inference wins on residency, offline operation and predictable cost — not on raw price. At October 2026 list prices, a $429 GPU only pays for itself after roughly 24,000 Opus-class queries or about 950,000 Haiku-class ones (author’s estimate).
- Quantization is nearly free down to about 5 bits, a small tax at 4, and a cliff below 3: on Llama-3-8B, Q4_K_M adds 0.18 perplexity; Q2_K adds 3.52.
- Modern models are more fragile than older ones. The same quant types cost Llama 3 roughly three to four times the perplexity they cost LLaMA-1, so the old “bigger model at 2 bits” trick no longer holds.
- The working rule: run the largest model that fits in VRAM at 4–5 bits with your real context length — never below ~3.5 bits without measuring.
- Budget memory as weights plus KV cache plus buffers. At 128K context, a 70B model’s KV cache (~43 GB) is as large as its 4-bit weights.
- Production is mostly not about the model: authenticate the endpoint, keep it off the public internet, pin model file hashes, set context and concurrency deliberately, and read the licence.
One of the production systems I have built never talks to the internet. It is a retrieval-augmented assistant for an organisation whose documents are not allowed to leave the building, so every embedding and every answer comes from an open-weight model running on the same machine as the user. When people ask whether that is a toy, my answer is no — but only because of a decision most tutorials treat as a footnote: how the model is quantized, and whether it actually fits in memory with the context the job needs.
The argument of this article is simple. For workloads bound by privacy, data residency, offline operation or predictable cost, a well-quantized open-weight model on ordinary Windows hardware is now a credible production option. Not for everything, and not because local is cheaper — it usually is not. It is credible because three things have matured at once: quantization formats that lose almost nothing at 4–5 bits, runtimes that install with one command and expose an OpenAI-compatible API, and open-weight models released under permissive licences, sometimes already quantized by the vendor. The corollary is the part people get wrong: success depends less on which model you pick than on the quantization and memory budget you fit it into.
Here is the route. I start with why local inference matters now and what the honest economics look like. I then lay out the evidence on quantization — size, quality and speed — including a result that overturns a popular rule of thumb. I offer a decision framework, then go deep on four dimensions: how quantization actually works, the memory arithmetic, hardware tiers on Windows, and runtimes and serving. I close with cases, counterpoints, implications by role, a 90-day plan and the limits of what this evidence can tell you.
Context: why this matters now
There are four legitimate reasons to run a model locally, and only one of them is cost.
Residency and privacy. In regulated settings — health, legal, finance, government — sending document text to a third-party API is often a compliance question before it is an engineering one. A local model removes the question: no egress, no processor agreement, no cross-border transfer. Offline and edge operation. Field teams, ships, clinics with poor connectivity and air-gapped networks cannot depend on an API at all. Latency and control. A local model has no rate limits, no surprise deprecations and no queue you do not own. Cost at very high, steady volume — but this is the weakest of the four, and I want to be precise about why.
The supply side has shifted decisively. Vendors now ship models designed to be quantized. Google released quantization-aware-trained (QAT) versions of Gemma 3 in April 2025, cutting the weights of the 27B model from 54 GB to 14.1 GB so that it runs on a single 24 GB RTX 3090 (Google). OpenAI’s gpt-oss models were post-trained with MXFP4 quantization of their mixture-of-experts weights; the 20B model (21B parameters, 3.6B active) is stated to run within 16 GB of memory, under Apache-2.0 (model card). The 2026 open-weight field — Qwen, Gemma 4 with official QAT q4_0 GGUFs, Mistral Small 4, DeepSeek, gpt-oss — is large and mostly permissively licensed.
Exhibit 1
Vendors now ship models built to be quantized: Google’s 4-bit Gemma 3 27B fits a single 24 GB gaming card
VRAM to load weights, Gemma 3 at int4 (QAT); BF16 shown for comparison (GB)
Weights only, as Google notes: the KV cache for your context length comes on top. Google names the RTX 3090 (24 GB) for 27B and an RTX 4060 Laptop GPU (8 GB) for 12B.
Source: Google Developers Blog, 18 Apr 2025
View data table
| Model | BF16 (GB) | int4 QAT (GB) |
|---|---|---|
| Gemma 3 27B | 54 | 14.1 |
| Gemma 3 12B | 24 | 6.6 |
| Gemma 3 4B | 8 | 2.6 |
| Gemma 3 1B | 2 | 0.5 |
Now the economics, honestly. Small hosted models have become extraordinarily cheap. At October 2026 list prices, Claude Haiku 5.5 costs $0.10 per million input tokens and $0.50 per million output tokens (Anthropic); Gemini 3.5 Flash-Lite is $0.30 and $2.50 (Google). Take a typical retrieval-augmented query — about 3,000 tokens of prompt and retrieved context, 300 tokens of answer — and a 16 GB RTX 5060 Ti, which launched at $429 (PCGamesN). Exhibit 2 shows how many queries it takes before the card has paid for itself in avoided API spend.
Exhibit 2
On price alone, local rarely wins: a $429 GPU needs ~950,000 queries to beat a Haiku-class API
Queries needed for avoided API spend to equal a $429 GPU (thousands); 3,000 input + 300 output tokens per query
Author’s estimate. Ignores electricity, the rest of the PC, engineering time and — most importantly — the quality gap: a local 8B model is not equivalent to Opus. The point is the order of magnitude, not the exact figure.
View data table
| API (input / output per 1M tokens) | Cost per query | Queries to $429 |
|---|---|---|
| Claude Opus 5.5 ($4 / $20) | $0.0180 | ~23,800 |
| Claude Sonnet 5.5 ($2 / $10) | $0.0090 | ~47,700 |
| Gemini 3.5 Flash-Lite ($0.30 / $2.50) | $0.00165 | ~260,000 |
| Claude Haiku 5.5 ($0.10 / $0.50) | $0.00045 | ~953,000 |
Read Exhibit 2 carefully, because it cuts both ways. Against frontier-priced models, a modest GPU pays back within tens of thousands of queries — a few months for a busy internal tool. Against the cheapest hosted tier, it takes close to a million. So the cost case for local is narrow: high, steady volume on tasks where a small model is good enough. The stronger case is almost always the first three reasons — residency, offline, control — where the hosted option is not on the table at all. If you are choosing local to save money on a low-volume workload with no data constraints, you are probably making a mistake.
The evidence: what quantization costs and what it buys
Quantization stores a model’s weights in fewer bits than the 16 used at full precision. The format you will meet on Windows is GGUF, the file format of llama.cpp and of the tools built on that ecosystem. Three questions decide whether a quantized model is fit for production: how much smaller it gets, how much quality it loses, and how much faster it runs.
Size: a 4-bit quant is under a third of full precision
llama.cpp’s quantize README publishes the effective bits per weight (bpw) of each type, measured on Llama-3.1-8B (README). Effective bpw is always a little above the nominal figure because each block of weights also stores scales.
Exhibit 3
Q4_K_M keeps an 8B model at under a third of its full-precision size
Effective bits per weight by GGUF quantization type, measured on Llama-3.1-8B
Source: llama.cpp, tools/quantize/README.md
View data table
| Type | Bits per weight | Size (GiB) |
|---|---|---|
| F16 | 16.00 | 14.96 |
| Q8_0 | 8.50 | 7.95 |
| Q6_K | 6.56 | 6.14 |
| Q5_K_M | 5.70 | 5.33 |
| Q4_K_M | 4.89 | 4.58 |
| IQ4_XS | 4.46 | 4.17 |
| Q3_K_M | 4.00 | 3.74 |
| Q2_K | 3.16 | 2.95 |
| IQ2_XS | 2.59 | 2.42 |
Quality: almost free to 5 bits, a small tax at 4, a cliff below 3
The standard quality measure is the increase in perplexity — roughly, how surprised the model is by held-out text — relative to full precision. llama.cpp’s quantize.cpp records these deltas for Llama-3-8B (source). The curve is the whole story.
Exhibit 4
Quality loss is negligible until about 4 bits, then falls off a cliff
Increase in perplexity vs FP16 on Llama-3-8B (lower is better)
Source: llama.cpp, tools/quantize/quantize.cpp
View data table
| Type | + perplexity |
|---|---|
| Q8_0 | +0.0026 |
| Q6_K | +0.0217 |
| Q5_K_M | +0.0569 |
| Q5_K_S | +0.1049 |
| Q4_K_M | +0.1754 |
| Q4_K_S | +0.2689 |
| Q4_0 | +0.4685 |
| Q3_K_L | +0.5562 |
| Q3_K_M | +0.6569 |
| Q3_K_S | +1.6321 |
| Q2_K | +3.5199 |
Two details matter. First, the “K” types beat the older plain types at similar size: Q4_K_M adds 0.18 perplexity while Q4_0 adds 0.47, for a file that is only marginally larger. Second, the gap between Q3_K_M (+0.66) and Q3_K_S (+1.63) shows that the mix of precisions across tensors matters as much as the headline bit count — a point I return to in the deep dive.
Size versus bits: the old rule, and why it broke
For years the community rule of thumb was: at a fixed memory budget, take the bigger model at fewer bits. The original k-quants pull request, which introduced the Q2_K–Q6_K family in June 2023, contains the data behind that rule (PR #1684). On LLaMA-1, every 13B quant — even Q2_K at 5.13 GB — had lower perplexity than the 7B model at full precision (13.0 GB).
Exhibit 5
On LLaMA-1, every 13B quant beat the 7B model at full precision — even at 2 bits
Perplexity by quantization type, LLaMA-1 7B vs 13B (lower is better)
File sizes from the same table: 7B F16 13.0 GB, 7B Q6_K 5.15 GB; 13B Q2_K 5.13 GB, 13B Q4_K_M 7.32 GB. At about 5 GB, 13B Q2_K (5.85) beat 7B Q6_K (5.91).
Source: llama.cpp PR #1684 (k-quants), June 2023
View data table
| Type | 7B | 13B |
|---|---|---|
| Q2_K | 6.7764 | 5.8545 |
| Q3_K_M | 6.1503 | 5.4498 |
| Q4_K_M | 5.9601 | 5.3002 |
| Q5_K_M | 5.9208 | 5.2638 |
| Q6_K | 5.911 | 5.2568 |
| F16 | 5.9066 | 5.2543 |
That rule does not transfer cleanly to modern models. Compare the perplexity penalties for the same quant types on LLaMA-1 7B (from PR #1684) and on Llama-3-8B (from quantize.cpp). Llama 3 pays roughly three to four times as much at every level, and at Q2_K the penalty jumps from 0.87 to 3.52. An academic study of Llama 3 quantization reached the same qualitative conclusion: “non-negligible degradation”, “particularly under ultra-low bit widths” (Huang et al.). The usual explanation — which I offer as a hypothesis, not a finding — is that models trained on far more tokens pack more information into each weight, leaving less redundancy for quantization to discard.
Exhibit 6
The same quant costs Llama 3 roughly three to four times the quality it cost LLaMA-1
Increase in perplexity vs full precision, by quant type and model
Directional comparison only: different tokenizers, evaluation runs and llama.cpp versions. Perplexities are not comparable across models in absolute terms; the deltas give a rough sense of fragility.
View data table
| Type | LLaMA-1 7B | Llama-3-8B |
|---|---|---|
| Q4_K_M | +0.054 | +0.175 |
| Q3_K_M | +0.244 | +0.657 |
| Q2_K | +0.870 | +3.520 |
The practical consequence is a revised rule: the largest model that fits at 4–5 bits, never below about 3.5 bits without measuring on your own task. “Bigger at 2 bits” was good advice for 2023 models; for 2025–2026 models it is a gamble.
Speed: smaller weights, faster tokens
Generating each token requires reading essentially every weight from memory once, so on consumer hardware generation speed is largely limited by memory bandwidth. Fewer bytes per weight means more tokens per second. In llama.cpp’s current README, Llama-3.1-8B generated 71.9 tokens per second at Q4_K_M against 29.2 at F16 — about 2.5 times faster — on hardware the README does not specify. The k-quants PR gives a hardware breakdown for the 7B model (Exhibit 7).
Exhibit 7
Quantizing to Q4_K_M roughly tripled generation speed on CPU and nearly quadrupled it on GPU
Text generation, LLaMA-1 7B, tokens per second (converted from published ms per token)
2023 llama.cpp build; current builds and models are faster in absolute terms. Ryzen figures use 4 threads; M2 Max uses 8. The ratio, not the absolute number, is the point.
Source: llama.cpp PR #1684 (k-quants), June 2023
View data table
| Hardware | F16 (ms/tok) | Q4_K_M (ms/tok) | Q4_K_M (t/s) |
|---|---|---|---|
| RTX 4080 | 60 | 16 | 62.5 |
| Apple M2 Max (8 threads) | 111 | 40 | 25 |
| Ryzen 9 7950X (4 threads) | 214 | 71 | 14.1 |
Speed is a quality attribute in production. A model that streams at 60 tokens per second feels instant; one at 5 tokens per second makes a 300-token answer take a minute, and users abandon it. That is why the CPU rows matter: a 7B model at Q4_K_M on a desktop CPU is usable for a single user, while the same model at F16 is not.
A framework: fit first, then choose
Most local-LLM projects I see start with “which model is best?” and end with a model that does not fit, spills into system RAM and crawls. I reverse the order. The decision stack below starts from the workload and the memory budget, and only then picks a model.
Exhibit 8
Decide in this order: eligibility, budget, quant floor, then the biggest model that fits
The local-LLM decision stack — Author’s framework
- 01EligibilityIs there a residency, offline, control or high-volume reason? If not, use a hosted API.
- 02Memory budgetVRAM (or RAM) minus KV cache for your real context and concurrency, minus ~1 GB of buffers.
- 03Quant floorQ4_K_M or IQ4_XS as default; Q5_K_M–Q6_K if it fits; below ~3.5 bpw only with evidence.
- 04Largest model that fitsPick the strongest licence-compatible model whose file fits the remaining budget.
- 05Runtime and servingOllama, LM Studio or llama.cpp behind an authenticated OpenAI-compatible endpoint.
- 06Evaluate on your task50–100 real questions, scored against the hosted baseline. Perplexity is not your metric.
The framework encodes the thesis. Steps two and three — the memory budget and the quant floor — determine what is possible before any model is named. Step six is the guard rail: perplexity is a useful proxy for comparing quants of one model, but it says little about whether a model can follow your instructions, cite your documents or refuse when it does not know.
Deep dive 1: how quantization actually works
It helps to know what the letters mean, because they predict behaviour.
Block-wise quantization. GGUF quant types do not use a single scale for a whole tensor. They split weights into small blocks and store a scale per block, so an outlier in one block does not ruin precision everywhere else. The simplest types are “type-0”, where a weight is reconstructed as w = d × q (a block scale times a small integer), and “type-1”, which adds a block minimum: w = d × q + m. Q4_0 and Q8_0 are the classic plain types.
K-quants. The k-quants introduced in PR #1684 add a second level. Weights are grouped into super-blocks of 256, split into sub-blocks of 16 or 32; the sub-block scales (and minimums) are themselves quantized to 4–8 bits, with one higher-precision scale per super-block (PR #1684). That is why Q4_K is about 4.5 bpw and Q6_K about 6.56. The suffixes _S, _M and _L are mixes: the same base type for most tensors, but higher precision for the ones that hurt most when compressed. In the PR’s definition, Q4_K_M uses Q6_K for half of the attention.wv and feed_forward.w2 tensors and Q4_K elsewhere; Q3_K_M promotes attention.wv, attention.wo and feed_forward.w2 to Q4_K. This is the mechanism behind Exhibit 4’s gap between Q3_K_S and Q3_K_M: spending a few extra bits in the right tensors buys a large share of the quality back.
I-quants. The IQ types, introduced in early 2024, use a different trick at very low bit rates. IQ2_XXS, for example, quantizes weights in groups of eight and encodes their magnitudes as an index into a 256-entry codebook drawn from the E8 lattice, with signs stored using a parity trick — ideas the author credits partly to the QuIP# research (PR #4773). The effect is better quality per bit at 2–4 bpw, at the cost of slower decoding on some hardware. IQ4_XS (4.46 bpw) is a useful alternative to Q4_K_M when a model is just slightly too big.
Importance matrices. Not all weights matter equally. llama.cpp’s imatrix tool runs calibration text through the model and records, for each weight column, the average squared activation; the quantizer then minimises error weighted by that importance rather than treating every weight alike (PR #4861; imatrix README). Importance matrices matter most at low bit rates. The practical upshot: when downloading 3-bit or IQ quants, prefer publishers who state they used an imatrix, and if you quantize yourself, calibrate on text that resembles your workload.
# Build an importance matrix from calibration text, then quantize with it
llama-imatrix -m model-f16.gguf -f calibration-data.txt -ngl 99
llama-quantize --imatrix imatrix.gguf model-f16.gguf model-IQ4_XS.gguf IQ4_XS
Quantization-aware training. QAT, as in Google’s Gemma 3 release, goes further: the model is trained while simulating low-precision arithmetic, so it learns weights that survive quantization. Google reports that QAT reduced the perplexity drop at Q4_0 by 54% (Google). When a vendor ships an official QAT checkpoint, it is usually the best 4-bit option available.
Failure mode and how to measure. The characteristic failure of over-quantization is not gibberish; it is subtle drift — slightly worse instruction following, more formatting mistakes, weaker recall of rare facts. You will not see it in a demo. Measure it with a fixed evaluation set run against two or three quants of the same model, and compare against a hosted baseline.
Deep dive 2: the memory arithmetic
A model needs memory for three things: its weights, its key-value (KV) cache, and working buffers.
Weights are approximately parameters × bits per weight ÷ 8. For Llama 3.1 8B at Q4_K_M: about 8 billion × 4.89 ÷ 8 ≈ 4.9 GB, matching the 4.92 GB file on Hugging Face (bartowski). For Llama 3.3 70B at Q4_K_M the file is 42.52 GB; at IQ2_XS it is 21.14 GB; at F16 it is 141.12 GB (bartowski).
KV cache is the part people forget. For each token of context, the model stores a key and a value vector in every layer:
KV bytes per token = 2 (K and V) × layers × KV heads × head dimension × bytes per element
The model configs give the inputs. Llama 3.1 8B has 32 layers, 8 KV heads and a head dimension of 128; Llama 3.3 70B has 80 layers, 8 KV heads and a head dimension of 128 (8B config; 70B config). At FP16 (2 bytes), that is 2 × 32 × 8 × 128 × 2 = 131,072 bytes, or 128 KiB per token, for the 8B model, and 2 × 80 × 8 × 128 × 2 = 327,680 bytes, or 320 KiB per token, for the 70B model. Multiply by context length.
Exhibit 9
At long context, the KV cache rivals the model: a 70B model at 128K needs ~43 GB of cache alone
FP16 KV cache size by model and context length (GB)
Estimate for one sequence. Parallel requests multiply it. A q8_0 KV cache roughly halves these figures, per Ollama’s documentation.
Source: Author’s calculation from model configs (Hugging Face) and the standard KV-cache formula
View data table
| Model · context | KV cache (GB) |
|---|---|
| 8B · 8K | 1.07 |
| 8B · 32K | 4.29 |
| 8B · 128K | 17.18 |
| 70B · 8K | 2.68 |
| 70B · 32K | 10.74 |
| 70B · 128K | 42.95 |
Buffers and headroom. Runtimes also allocate compute buffers, and Windows reserves some VRAM for the desktop. My rule of thumb is 0.5–1 GB, more on cards that also drive displays. Put together, the worked examples look like this:
Exhibit 10
An 8B model fits an 8 GB card at short context; a 70B model does not fit any single gaming card
Worked memory budgets: weights + FP16 KV cache + ~1 GB buffers — Author’s estimate
| Weights | KV cache | Total (est.) | Realistic home | |
|---|---|---|---|---|
| 8B Q4_K_M · 8K | 4.9 GB | 1.1 GB | ~7 GB | 8 GB GPU (tight) or 12 GB |
| 8B Q4_K_M · 32K | 4.9 GB | 4.3 GB | ~10 GB | 12–16 GB GPU; ~8 GB with q8_0 KV |
| 8B Q8_0 · 8K | 8.5 GB | 1.1 GB | ~10.5 GB | 12–16 GB GPU |
| 8B Q4_K_M · 128K | 4.9 GB | 17.2 GB | ~23 GB | 24 GB GPU — context costs more than the model |
| 70B IQ2_XS · 8K | 21.1 GB | 2.7 GB | ~25 GB | Just over 24 GB, and below the quality floor |
| 70B Q4_K_M · 8K | 42.5 GB | 2.7 GB | ~46 GB | Two 24 GB GPUs, or a slow GPU+CPU split |
Estimates for a single request. With OLLAMA_NUM_PARALLEL or llama.cpp slots above 1, multiply the KV column.
The most important row is the fourth. Teams often pick a small model to save memory and then set a 128K context “because the model supports it”, quietly spending four times the model’s size on cache. Set context to what the task needs. For retrieval-augmented generation, 8K–16K is usually enough: you are sending the top few chunks, not the library.
Failure mode and measurement. When a model does not fit in VRAM, runtimes offload layers to the CPU. It still works, so nobody notices — except that generation speed drops sharply. On Ollama, ollama ps shows how much of a loaded model sits on the GPU versus the CPU; anything other than 100% GPU on a latency-sensitive service is a bug.
Deep dive 3: hardware tiers on Windows
The runtime documentation sets the floor. Ollama requires Windows 10 22H2 or newer (Ollama, Windows). For NVIDIA, it supports compute capability 5.0 and above with driver 550 or newer; cards of compute capability 5.0–6.2 need driver 570 or newer (Ollama, GPU) — the Windows page itself lists 551.61 as the minimum, so simply install a current driver. For AMD on Windows, ROCm acceleration needs a ROCm v7 / HIP7-capable driver and a supported card — RX 7900 XTX, 7900 XT, 7900 GRE, 7800 XT, 7700 XT, 7600 XT, 7600 or the Radeon PRO W7000 series. Everything else can use Vulkan, which Ollama enables by default when the backend is installed (set OLLAMA_VULKAN=0 to disable it). llama.cpp itself supports CUDA, HIP, Vulkan and SYCL (for Intel GPUs), among other backends (llama.cpp). LM Studio requires AVX2 on x64 CPUs, runs on Snapdragon X Elite machines, and recommends 16 GB of RAM and 4 GB of dedicated VRAM (LM Studio).
Exhibit 11
Match the model to the memory you have, not the other way round
Hardware tiers for Windows — Author’s framework, grounded in the vendor documentation cited above
| Typical hardware | What runs well | Start with | |
|---|---|---|---|
| CPU only, 16–32 GB RAM | AVX2 laptop or desktop, no discrete GPU | 1–4B models interactively; 7–8B for a single patient user | Q4_K_M |
| 8 GB VRAM | RTX 4060 / laptop GPUs | 7–9B at 4–8K context; Gemma 3 12B QAT per Google | Q4_K_M or vendor QAT |
| 12–16 GB VRAM | RTX 5060 Ti 16 GB class | 8B at Q8_0 or long context; 12–14B at Q4–Q5; gpt-oss-20b | Q5_K_M–Q6_K |
| 24–32 GB VRAM | RTX 3090 / 4090 / 5090 class | 24–32B at Q4 (Gemma 3 27B QAT is 14.1 GB) | Q4_K_M, IQ4_XS |
| AMD Radeon | RX 7600–7900 XTX | As per VRAM tier, via ROCm v7; older cards via Vulkan | Same as NVIDIA tier |
| 70B ambitions | Single consumer GPU | Does not fit at 4 bits (~46 GB with 8K context) | Two GPUs, a workstation card, or a smaller model |
Author’s guidance. Exact fit depends on architecture, context length and concurrency; verify with the arithmetic in Exhibit 10.
Two practical notes. First, laptop GPUs share thermal budgets with the CPU; sustained throughput on a thin laptop is lower than its first minute suggests, so benchmark for ten minutes, not ten seconds. Second, if you are buying hardware for this, VRAM capacity matters more than raw compute: a 16 GB mid-range card runs more useful models than a faster 8 GB one.
Deep dive 4: runtimes, setup and serving
Three runtimes cover almost every Windows use case. They share the GGUF format, so a model file works across them.
Exhibit 12
Ollama for services, LM Studio for exploration, llama.cpp for control
Runtime comparison on Windows — Author’s framework; facts from each project’s documentation
| Ollama | LM Studio | llama.cpp | |
|---|---|---|---|
| Install | winget install Ollama.Ollama, or OllamaSetup.exe (no admin rights) | winget install ElementLabs.LMStudio | winget install llama.cpp, or the PowerShell install script |
| Interface | Background service + CLI | Desktop GUI with model browser | CLI and server binaries |
| API | OpenAI-compatible at localhost:11434/v1 | OpenAI-compatible at localhost:1234/v1 | OpenAI-compatible chat, responses and embeddings routes |
| Concurrency | OLLAMA_NUM_PARALLEL (default 1); queue of 512 | Managed by the app | Server slots (-np), continuous batching |
| Auth | None built in; binds 127.0.0.1 by default | Local server; treat as unauthenticated | --api-key; binds 127.0.0.1 by default |
| Best for | A shared internal service on one box | Comparing quants and prompts quickly | Tuning, custom quants, unusual hardware |
Defaults as documented in October 2026; check release notes, as these projects change monthly.
Step 1 — install and run a first model (Ollama). Ollama installs into your user account without administrator rights and serves an API on http://localhost:11434 (Ollama, Windows). You can pull a specific GGUF quant straight from Hugging Face:
winget install Ollama.Ollama
# or: irm https://ollama.com/install.ps1 | iex
ollama run hf.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M
ollama ps # check the model is 100% on GPU
Step 2 — set context and memory deliberately. Ollama’s documented default context window is 4,096 tokens, overridable with OLLAMA_CONTEXT_LENGTH or per request with num_ctx (Ollama FAQ). The KV cache can be quantized with OLLAMA_KV_CACHE_TYPE when Flash Attention is on: q8_0 uses about half the memory of f16 “with a very small loss in precision”; q4_0 about a quarter, with a loss that “may be more noticeable at higher context sizes”. Models live in C:\Users\%USERNAME%\.ollama\models unless you set OLLAMA_MODELS. On Windows, set these as user environment variables, then quit Ollama from the system tray and restart it:
setx OLLAMA_CONTEXT_LENGTH 16384
setx OLLAMA_FLASH_ATTENTION 1
setx OLLAMA_KV_CACHE_TYPE q8_0
setx OLLAMA_NUM_PARALLEL 2
setx OLLAMA_MODELS "D:\models\ollama"
Step 3 — or use LM Studio to compare quants. LM Studio is the fastest way to try three quants of the same model side by side with a GUI. Since July 2025 it has been free for use at work as well as at home (LM Studio).
winget install ElementLabs.LMStudio
Step 4 — or llama.cpp for full control. llama.cpp’s README now documents a unified llama command, plus a PowerShell installer (irm https://llama.app/install.ps1 | iex); older releases name the binaries llama-cli and llama-server. The server supports an API key, a context size, parallel slots and KV-cache types (-c, -np, --api-key, -ctk/-ctv), and binds to 127.0.0.1 by default (server README).
winget install llama.cpp
llama cli -hf ggml-org/Qwen3.5-0.8B-GGUF # quick interactive test
llama serve -hf ggml-org/Qwen3.5-0.8B-GGUF # OpenAI-compatible server
Step 5 — serve it to applications. All three expose OpenAI-compatible endpoints, which means existing client code needs only a base URL change. With Ollama the API key is required by the client library but ignored by the server (Ollama):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1/", api_key="ollama")
reply = client.chat.completions.create(
model="hf.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF:Q4_K_M",
messages=[{"role": "user", "content": "Summarise this clause in one sentence: ..."}],
)
print(reply.choices[0].message.content)
That portability is strategically important. If your application talks to an OpenAI-compatible interface, you can move a workload between local and hosted models by configuration — and you should design for exactly that, because the right answer for a workload changes as models and prices move.
Production concerns
Concurrency. Ollama processes one request per model at a time by default and queues up to 512 more; raising OLLAMA_NUM_PARALLEL increases the context memory proportionally (Ollama FAQ). A single consumer GPU is a service for a team, not for a company. Load-test with realistic prompt lengths before you promise anyone a response time.
Context length. Set it explicitly and test at the limit. A silently truncated prompt is one of the most common causes of “the local model is worse” complaints in retrieval systems: the retrieved passages never reached the model.
Network exposure. Ollama binds to 127.0.0.1 by default and has no built-in authentication. Changing OLLAMA_HOST to expose it on a network without putting authentication in front is how incidents happen. In September 2025, Cisco researchers used Shodan to find 1,139 exposed Ollama servers, 214 of them actively hosting models (Cisco). Put a reverse proxy with authentication, or llama.cpp’s --api-key, in front of anything reachable from another machine, and restrict it to trusted networks.
Model-file security. A GGUF file is data, but the parser that reads it is code. In February 2024, Cisco Talos disclosed heap-overflow vulnerabilities in llama.cpp’s GGUF parsing, including CVE-2024-23605 (CVSS 8.8), where “a specially crafted .gguf file can lead to code execution” (Talos). Treat model files like executables: download from known publishers, record a hash (Get-FileHash model.gguf -Algorithm SHA256), store approved files in a controlled location and keep runtimes updated.
Licences. “Open weights” is not one licence. Gemma 4, Qwen3.8, Mistral Small 4 and gpt-oss are Apache-2.0; DeepSeek V4.1-Flash is MIT; Llama models use Meta’s own licences. The Llama 3.1 Community License, for example, requires a separate licence if your products exceeded 700 million monthly active users, asks you to “prominently display ‘Built with Llama’” and binds you to an acceptable use policy (Meta). Read the model card before production, and record the licence alongside the hash.
Updates. Pin versions. A new runtime release can change defaults (context length, KV handling, GPU selection); a re-uploaded GGUF can change behaviour. Upgrade on a schedule, re-run your evaluation set, then promote.
Case examples
Google’s Gemma 3 QAT release (April 2025). Google trained 4-bit-aware versions of Gemma 3 and published them for consumer GPUs, cutting the 27B model’s weights from 54 GB to 14.1 GB and reducing the Q4_0 perplexity drop by 54% compared with naive quantization (Google). Lesson: when a vendor ships a QAT checkpoint, it moves the quality-size frontier; start there.
OpenAI’s gpt-oss (August 2025). OpenAI post-trained its open-weight models with MXFP4 quantization of the mixture-of-experts weights and evaluated them in that form; the 20B model runs within 16 GB of memory under Apache-2.0 (model card). Lesson: quantization is no longer something the community does to a model after release — it is part of how frontier labs design open models for local hardware.
Exposed Ollama servers (September 2025). Cisco’s scan found over a thousand Ollama instances on the public internet without authentication (Cisco). Lesson: the easiest local runtime is also easy to misconfigure. The model was never the risk; the endpoint was.
Field notes: an offline RAG system. The privacy-first RAG system I mentioned at the start runs entirely on local hardware: Ollama serves Gemma 2 (2B or 9B) for generation and nomic-embed-text for embeddings, ChromaDB stores vectors on local disk, a FastAPI backend handles ingestion and queries, DVC versions each ingestion run, MLflow tracks retrieval experiments and Evidently monitors embedding and query drift. It uses CUDA where there is an NVIDIA GPU and Metal on a Mac, and it makes no outbound calls. Because the retrieval interface is identical to the cloud version, the only thing that changes between local and hosted is a model name.
Counterpoints
Implications by stakeholder
Executives and risk owners. Local inference converts a data-protection question into an infrastructure question. That is a good trade for regulated data, and a poor one for everything else. Ask for the eligibility case (step one of Exhibit 8) in writing, and expect to fund evaluation and security work, not just hardware.
Engineering leads. Design every LLM call behind an OpenAI-compatible interface with the model name in configuration, so workloads can move between local and hosted without code changes. Own the operational basics: authenticated endpoints, pinned model hashes, scheduled upgrades with regression runs, and monitoring of GPU residency and latency.
Practitioners. Learn the memory arithmetic and the quant ladder well enough to size a deployment on a napkin. Build a small, honest evaluation set early; it is the only thing that will settle arguments about which quant or model to use.
Security and compliance teams. Treat GGUF files and runtimes as software supply chain: approved sources, hashes, version control and patching. Treat a local LLM endpoint as an unauthenticated API until proven otherwise.
What to do next: a 90-day plan
Days 1–30: decide and size.
- List candidate workloads and mark which have a residency, offline, control or volume reason. Drop the rest.
- For each survivor, record the real context length and concurrency. Run the Exhibit 10 arithmetic.
- Build an evaluation set of 50–100 real inputs with expected answers or rubrics, and score the hosted baseline.
- On existing hardware, test two or three quants (Q4_K_M, Q5_K_M, Q6_K) of one or two licence-compatible models in LM Studio or Ollama.
Days 31–60: pilot. 5. Stand up Ollama or llama.cpp on one machine with explicit context, KV-cache type and parallelism settings. 6. Put authentication in front of it, restrict it to the internal network, and record model hashes and licences. 7. Run a pilot with real users; log latency, GPU residency and failure cases, and re-score the evaluation set.
Days 61–90: harden or hand back. 8. If the local model is within an acceptable margin of the baseline on your evaluation set, harden: monitoring, upgrade cadence, runbooks. 9. If not, try the next tier up (bigger model or higher quant) once. If it still fails, return the workload to a hosted model — and keep the interface, so you can try again when the next open-weight generation arrives.
Limitations and methodology
The quality evidence is perplexity, measured mostly on two models: Llama-3-8B for the current deltas and LLaMA-1 7B/13B for the size comparison. Perplexity is a proxy; it does not measure instruction following, grounding or reasoning, and its values are not comparable across models with different tokenizers. The cross-generation comparison in Exhibit 6 mixes evaluation runs and llama.cpp versions and should be read as directional.
Speed figures are hardware-dependent. The README’s 2.5× speed-up does not state its hardware; the PR #1684 timings are from a 2023 build on a 2023 model. Absolute speeds on current builds will differ; ratios are more stable. The memory figures are calculations from published configs and file sizes plus my own rule of thumb for buffers; your runtime will report slightly different numbers. The break-even estimate uses list prices on 14 October 2026, one GPU’s launch price, and an assumed token mix; it ignores electricity, the rest of the machine and the capability gap. I have not presented benchmarks of my own here, and the field note above is flagged for confirmation.
Closing
The question “can I run a real model on a Windows PC?” has been answered: yes, and with the right quant it is fast enough to use. The more useful question is whether you should, and if so, how to fit it. For workloads where data cannot leave, networks cannot be relied on, or volume is high and steady, a well-quantized open-weight model is a credible production choice. Make the decision in the right order — eligibility, memory budget, quant floor, then the largest model that fits — secure the endpoint like any other service, and let your own evaluation set, not a leaderboard, have the final word.
In short
- Running AI on your own machine wins on privacy, working offline and control, not usually on price: a $429 graphics card only pays for itself after roughly 24,000 to 950,000 queries, depending on which cloud model you compare it with.
- Shrinking a model to about 4–5 bits per number costs almost nothing in quality; going below 3 bits falls off a cliff, and newer models are more fragile than older ones.
- Plan memory as the model plus its working memory for the conversation plus a little spare. Pick the biggest model that fits at 4–5 bits, then test it on your own real questions.
A photo straight off a good camera is a huge file. Save it as a decent JPEG and it shrinks to a fraction of the size, yet on your phone it looks the same. Squeeze it too hard, though, and faces turn into blocks. AI models work the same way. Shrink one carefully and it runs on an ordinary Windows PC with almost no loss; shrink it too far and it quietly gets worse. Whether a model on your own computer is a toy or a serious tool depends far more on that squeeze, and on whether the result fits in memory, than on which model you picked.
That is the argument in one sentence: for work where data must stay private, or costs must be predictable, a carefully shrunk open model on an ordinary Windows machine is now a credible choice for real use, and success depends less on which model you choose than on how much you shrink it and whether it fits in memory.
Jargon decoder
- LLM (large language model): the kind of AI behind chat assistants. It predicts text one small piece at a time.
- Open-weight model: a model whose files you can download and run yourself, such as Llama, Gemma or Qwen. “Weights” are the millions or billions of numbers the model learned.
- Running locally: the model runs on your own computer instead of a company’s servers in the cloud.
- Hosted API: paying a provider per use to run a model on their servers.
- Quantization: storing each of the model’s numbers with fewer bits, like saving a photo as a smaller JPEG. “4-bit” means each number uses 4 bits instead of the usual 16.
- GGUF, Q4_K_M, Q2_K: the file format for shrunk models on Windows, and labels for how hard they were squeezed. The digit is roughly the bits per number.
- VRAM: the memory on your graphics card. The model needs to fit here to run fast.
- Context and KV cache: context is how much text the model can consider at once; the KV cache is the working memory it uses to hold that text.
- Perplexity: a quality score for how surprised a model is by real text. When comparing shrunk versions of one model, a bigger increase means more damage.
- Token: a chunk of text, roughly part of a word. Speed is measured in tokens per second.
Why run a model on your own computer?
There are four good reasons, and only one is cost.
- Privacy and data residency. In health, law, finance and government, sending document text to an outside company is often a compliance question before it is a technical one. A local model removes the question.
- Working offline. Field teams, ships, clinics with poor connections and sealed-off networks cannot depend on the cloud at all.
- Control. No usage limits, no surprise retirements of the model you rely on, no queue you do not own.
- Cost, but only at very high, steady volume. This is the weakest reason.
Why the weakest? Small cloud models have become extraordinarily cheap. Take a typical question with about 3,000 tokens going in and 300 coming out, and a 16 GB graphics card that launched at $429. Here is how many questions it takes before the card has paid for itself in cloud fees you avoided.
Exhibit 1
On price alone, local rarely wins: a $429 graphics card needs ~950,000 queries to beat the cheapest cloud model
Queries needed for avoided cloud fees to equal the cost of a $429 GPU (thousands)
Author's estimate. Ignores electricity, the rest of the PC, staff time and the quality gap: a small local model is not equivalent to a top cloud model. The point is the order of magnitude.
View data table
| Cloud model compared | Queries to $429 |
|---|---|
| Claude Opus 5.5 | ~23,800 |
| Claude Sonnet 5.5 | ~47,700 |
| Gemini 3.5 Flash-Lite | ~260,000 |
| Claude Haiku 5.5 | ~953,000 |
Against expensive top-tier models, the card pays back within tens of thousands of questions, a few months for a busy internal tool. Against the cheapest, it takes close to a million. So if you are choosing local just to save money on a small workload with no privacy constraint, you are probably making a mistake. The strong case is the first three reasons, where the cloud is not an option at all.
What changed is that model makers now ship models designed to be shrunk. In April 2025 Google released a 4-bit-trained version of its Gemma 3 27B model, cutting it from 54 GB to 14.1 GB, small enough for a single 24 GB gaming card.
Squeezing the model: how small is too small?
A full-precision model stores each number in 16 bits. The most common shrunk version, called Q4_K_M, uses just under 5, so the file is under a third of the size. It also runs faster: in one published test, an 8-billion-parameter model produced about 72 tokens per second when shrunk, against 29 at full size, roughly 2.5 times faster. Speed matters: a model that types at 60 tokens a second feels instant; one at 5 makes users give up.
But what does the squeeze cost in quality? Here is the extra “surprise” each level adds to Llama 3, compared with the full-size model.
Exhibit 2
Quality loss is tiny down to about 4 bits, then falls off a cliff
Increase in perplexity vs full precision on Llama-3-8B (lower is better)
Source: llama.cpp, tools/quantize/quantize.cpp
View data table
| Type | + perplexity |
|---|---|
| Q8_0 (8-bit) | +0.0026 |
| Q5_K_M (about 5-bit) | +0.0569 |
| Q4_K_M (about 4-bit) | +0.1754 |
| Q3_K_M (about 3-bit) | +0.6569 |
| Q2_K (about 2-bit) | +3.5199 |
Read it like the photo: nearly free down to about 5 bits, a small tax at 4, and a cliff below 3.
There is a twist. For years the popular rule was “take the bigger model at fewer bits”. On older models it held: every squeezed version of the 13-billion-parameter LLaMA-1, even at 2 bits, beat the smaller 7-billion one at full size. Newer models are more fragile. The same squeeze costs Llama 3 roughly three to four times as much quality as it cost LLaMA-1, and at 2 bits the damage jumps from 0.87 to 3.52. A likely explanation, though not a proven one, is that newer models are trained on far more text and pack more into every number, leaving less slack to throw away.
So the rule for today: run the largest model that fits at 4–5 bits, and never go below about 3.5 bits without testing it on your own work.
The suitcase problem: will it fit?
Think of your graphics card’s memory as a suitcase. Three things must go in: the model itself, the working memory for the conversation (the KV cache), and about half a gigabyte to a gigabyte of spare room for the software.
People forget the second item. The longer the text you let the model consider at once, the bigger its working memory gets, and at long lengths it can be as large as the model.
Exhibit 3
At long context, a model's working memory can be as large as the model itself
Memory needed for Llama 3.3 70B: 4-bit model file vs its working memory (KV cache) at two context lengths (GB)
Working memory is for one conversation at a time; serving several people at once multiplies it.
View data table
| Item | GB |
|---|---|
| Model file at 4-bit (Q4_K_M) | 42.5 |
| Working memory at 8K context | 2.7 |
| Working memory at 128K context | 43.0 |
The same thing happens to small models. An 8-billion-parameter model at 4 bits is about 4.9 GB, but set it to read 128K tokens at once “because it can” and its working memory adds about 17 GB, roughly four times the model. For most document-answering tools, 8K–16K is enough: you are sending the few most relevant passages, not the whole library.
What happens if it does not fit? The software quietly moves part of the model into the computer’s ordinary memory. It still works, so nobody notices, except that it becomes much slower. On Ollama, a command called ollama ps shows how much of the model is on the graphics card; anything less than 100% on a tool where speed matters is a bug.
That is why I decide in this order: is there a good reason to run locally at all; how much memory is left once working memory is counted; what is the minimum squeeze I will accept; and only then, which is the biggest model that fits. Then I test it on 50–100 real questions against a cloud model. The quality score in Exhibit 2 is useful for comparing versions of one model, but it cannot tell you whether a model follows your instructions or admits when it does not know.
Running it safely
Three tools cover almost everything on Windows: Ollama (a background service, good for a shared internal tool), LM Studio (a desktop app, good for comparing versions side by side) and llama.cpp (the engine underneath, for full control). All three speak the same language as OpenAI’s cloud service, so existing software can switch between local and cloud models by changing an address. That is worth designing for, because the right choice changes as prices and models move.
Most of the work of running it for real is not about the model:
- Lock the door. Ollama has no built-in password and is only reachable from your own machine by default. Open it to a network without adding protection and anyone can use it. In September 2025, Cisco researchers found 1,139 Ollama servers exposed on the public internet, 214 of them running models.
- Treat model files like programs. A flaw found in 2024 meant a specially crafted model file could run code on your machine. Download from known publishers, record each file’s fingerprint (a hash), and keep the software updated.
- Read the licence. “Open” is not one licence. Many models use Apache-2.0; Llama models use Meta’s own terms, including a requirement to display “Built with Llama”.
- Set limits on purpose. Choose the context length and the number of people served at once deliberately, and test at those limits.
If you remember one thing
Yes, you can run a real AI model on a Windows PC, and with the right squeeze it is fast enough to use. The better question is whether you should, and how to fit it. Decide in the right order: a real reason to stay local, the memory you have, a floor of about 4 bits, then the biggest model that fits. Lock down the endpoint like any other service. And let your own test questions, not a leaderboard, have the final word.
Sources
- llama.cpp — tools/quantize/README.md (bits per weight, sizes, throughput)
- llama.cpp — tools/quantize/quantize.cpp (perplexity deltas per quant type)
- llama.cpp PR #1684 — k-quants (design, LLaMA-1 7B/13B perplexity, sizes and timings)
- llama.cpp PR #4773 — 2-bit i-quants (IQ2_XXS, E8 lattice codebook)
- llama.cpp PR #4861 — Importance matrix calculation
- llama.cpp — tools/imatrix/README.md
- llama.cpp — README (install, backends, llama cli / llama serve)
- llama.cpp — tools/server/README.md (OpenAI-compatible server, flags)
- Ollama — Windows documentation
- Ollama — GPU support
- Ollama — FAQ (context length, concurrency, KV cache quantization, network binding)
- Ollama — OpenAI compatibility
- LM Studio — System requirements
- LM Studio — OpenAI compatibility endpoints
- LM Studio — “LM Studio is free for use at work” (8 Jul 2025)
- Hugging Face — bartowski/Meta-Llama-3.1-8B-Instruct-GGUF
- Hugging Face — bartowski/Llama-3.3-70B-Instruct-GGUF
- Hugging Face — Llama 3.1 8B Instruct config (layers, KV heads, head dim)
- Hugging Face — Llama 3.3 70B Instruct config (layers, KV heads, head dim)
- Google Developers Blog — Gemma 3 QAT models (18 Apr 2025)
- Hugging Face — openai/gpt-oss-20b model card
- Huang et al. — An empirical study of LLaMA3 quantization (arXiv:2404.14047)
- Liu et al. — Quantization Hurts Reasoning? (arXiv:2504.04823)
- Cisco — Detecting Exposed LLM Servers: A Shodan Case Study on Ollama (1 Sep 2025)
- Cisco Talos — TALOS-2024-1916 / CVE-2024-23605 (GGUF parsing heap overflow)
- Meta — Llama 3.1 Community License
- Anthropic — Models overview (pricing)
- Google — Gemini API models (pricing)
- PCGamesN — RTX 5060 Ti price and release date (secondary)