Build guide 02 · Local AI

The Local AI Box, three budgets

What a language model actually feels like at $400, $900 and $1,800 — measured on hardware in my house, with the commands printed so you can check me. Including the budget I won't print a number for, because I don't own that card.

Time: an evening Hardware: $400 – $1,800 Ongoing: about 100W while it's thinking Difficulty: you can copy-paste a terminal command

What this actually replaces

Same rule as the photo server: the money first, and honestly.

A chatbot subscription is $20/month. The cheapest box here is around $400, so call it a twenty-month payback. That sounds fine right up until you look at what you're comparing against. A 7-billion-parameter model running in your basement is not as smart as the model behind a $20 subscription. It isn't close, and anyone telling you otherwise has something to sell you.

So don't buy this to save $20. Buy it for the three things the subscription can't do:

  • Nothing leaves the house. Your notes, your finances, your medical letters, your kids' names, your employer's source code. The reason most people can't use a cloud model at work isn't the price.
  • There is no meter. Point it at ten thousand documents and it costs the same as pointing it at one. This is where local models genuinely win — bulk, boring, repetitive work you'd never authorise a per-call bill for.
  • It can't be deprecated, rate-limited, price-hiked or discontinued. The weights are a file on your disk. It works with the internet unplugged.

If none of those three matter to you, keep the $20 subscription and keep your weekend. That's a real answer and for a lot of people it's the right one.

Everything below was measured here Every tokens-per-second figure on this page came out of a command that ran on a machine in my house, and the commands are printed so you can run them on yours. Where I couldn't measure something, the number is missing rather than estimated — there's an entire budget tier below with an empty column for exactly that reason.

How to read a tokens-per-second number

A token is roughly three-quarters of a word. The number everyone quotes is generation speed — how fast the model writes its answer once it has started.

You read at about 250 words a minute, which is somewhere around 5 tokens per second. That's the line everything else is measured against:

Generation speedWhat it feels like
~5 tok/sExactly your reading speed. Usable, but you're never waiting less than you're reading, and long answers become a chore.
~10 tok/sComfortably ahead of you. This is the floor for something you'd actually reach for.
~50 tok/sFaster than you can follow. Feels like a website.
150+ tok/sAnswers arrive as a block. Fast enough to put in a loop and stop thinking about.

There is a second number nobody quotes and everybody feels: prompt processing speed — how fast it reads what you gave it, before it writes a single word. Paste in a document and that's the silence you sit through. It separates these budgets far more brutally than generation speed does, and it gets its own table further down.

What I measured it on

Two machines, both mine, stated plainly so you can discount the numbers appropriately.

MachineSpecWhat it's standing in for
Box A
desktop, Ubuntu
Intel i9-9900KF, 8 cores / 16 threads, 16GB DDR4
NVIDIA RTX 3070, 8GB
A desktop graphics card — and, because it's a working machine with other things running on it, the VRAM wall
Box B
laptop, Windows
Intel Core Ultra 9 185H, 16 cores / 22 threads, 16GB LPDDR5-7467
NVIDIA RTX 4070 Laptop, 8GB
The main comparison: the same machine with the graphics card switched on and off
Where these numbers flatter the cheap tier Both of those CPUs are considerably faster than the $170 refurbished office desktop the $400 tier is built around. Treat every CPU-only number below as an optimistic ceiling, not a promise — a six-year-old office i5 with slower memory will land under it. I don't own one, so I can't tell you by how much.

Software: Ollama 0.20.7, models at their default q4_K_M quantisation — qwen2.5:3b (1.9GB), qwen2.5:7b (4.7GB) and llama3.2:3b (2.0GB). Every figure is the median of three warm runs: the model was already loaded, so weight-loading time isn't hiding inside the result. CPU-only numbers were produced on the same machines by forcing every layer off the graphics card rather than by unplugging it.

The whole harness is this, against Ollama's HTTP API:

# evict whatever is resident first, so placement is deterministic
curl -s http://localhost:11434/api/generate -d '{"model":"qwen2.5:7b","keep_alive":0}'

# one warm-up call (thrown away), then the runs that count.
# "num_gpu": 0 forces CPU only. Remove it to let Ollama decide.
curl -s http://localhost:11434/api/generate -d '{
  "model": "qwen2.5:7b",
  "prompt": "Explain in 200 words why a local model differs from a cloud API.",
  "stream": false,
  "options": {"num_gpu": 0, "num_predict": 256,
              "temperature": 0, "seed": 42, "num_ctx": 2048}
}'

The reply carries eval_count and eval_duration (nanoseconds). Generation speed is one divided by the other; prompt speed is prompt_eval_count over prompt_eval_duration. That's the entire trick. There is nothing proprietary about any of it, which is why it bothers me how many published tokens-per-second numbers have no command printed next to them.

If you'd rather not write the loop: ollama run qwen2.5:7b --verbose "your prompt" prints the same statistics after every answer. Run it twice and use the second one — the first includes loading the model off disk.

The numbers

Same machine, same models, same questions. The only thing that changes between the two columns is whether the graphics card is allowed to do the work.

ModelCPU onlyOn the 8GB cardDifference
qwen2.5:3b
1.9GB
20.0 tok/s 97.2 tok/s 4.9×
qwen2.5:7b
4.7GB
9.5 tok/s 49.8 tok/s 5.2×

Box B. Median of three warm runs generating 256 tokens each; both GPU rows confirmed at 100% GPU placement, both CPU rows at 0%.

And the same exercise on Box A's desktop card, with a 3B model:

ModelCPU only
i9-9900KF, DDR4
RTX 3070 8GBDifference
llama3.2:3b
2.0GB
9.2 tok/s 165.1 tok/s 18×

Two things fall out of putting those tables next to each other, and both are more useful than any individual number:

  • Generation speed tracks memory bandwidth almost exactly. Box A's desktop RTX 3070 moves memory about 1.75× faster than Box B's laptop RTX 4070 on paper, and it produced a near-identically-sized 3B model about 1.7× faster in practice — 165 against 97. Not cores, not the generation on the box. Bandwidth and VRAM. Buy on those two numbers.
  • The same logic explains the CPU column. Box B's newer chip with LPDDR5-7467 memory ran a 3B model at 20 tok/s; Box A's older i9 on DDR4 managed 9.2 on a model the same size — roughly twice the memory speed, roughly twice the tokens. If you're building the no-graphics-card tier, the memory generation matters more than the badge on the CPU.

And now the number nobody quotes

Generation speed is the flattering metric. Here is the same 7B model on the same laptop, handed a ~2,900-token document — about four pages — and timed from send to the first word of the answer:

WherePrompt processingSilence before it says anything
On the 8GB card3,042 tok/s0.95 seconds
CPU only49 tok/s59 seconds

Sixty-two times. That is the real gap between these tiers, and it's the one you feel every single time you use the thing for work rather than chitchat. Summarise an email thread, ask a question about a manual, hand it a page of code — on the CPU box you are waiting a full minute, staring at nothing, before the first word appears. The generation speed you were shopping on barely matters next to that.

Running cost Measured on Box B's card: about 16W idle and about 104W while it's actually generating. At 30¢/kWh, an hour of real use a day is roughly 90¢ a month — and leaving it idling all day costs about four times more than using it. The electricity is not the reason to say no.

The three budgets

One rule runs through all three: you are buying video memory. Not cores, not the brand, not the generation. The model has to fit in VRAM or it doesn't run at full speed, and that single constraint decides everything else.

~$400 — the no-graphics-card box

PartWhat to get~PriceWhy
Whole machine Refurb small-form-factor desktop, Intel 8th-gen or newer i5/i7
Dell OptiPlex / Lenovo ThinkCentre M-series class
$170 The same box as the photo server guide. If you built that, you already own this tier — go and try it before you spend anything.
Memory 32GB DDR4 — and the fastest the board will take $45 With no graphics card the model lives in system RAM and its speed is your memory speed. See the 20 vs 9.2 tok/s above.
Fast storage 1TB NVMe SSD $60 Model files are 2–9GB each and get read in full on every cold start.
Roughly~$275–400Depending on what the refurb ships with

What it does: 3B models comfortably above reading speed, 7B models around it. Fine for short questions, classifying things, tidying text, and anything you can set running and walk away from. Painful the moment you paste in something long — that's the 59-second table above, and on a slower CPU than mine it will be worse.

~$900 — the one that actually works

PartWhat to get~PriceWhy
Graphics card Used RTX 3060 12GB
the 12GB version — the 8GB card wears almost the same name
$289 12GB is the cheapest amount of VRAM that holds a 7B model with room left over for a real context window. The single most important line on this page.
Host machine Used tower, 6+ cores, 32GB RAM, full-height PCIe slot $350 A slim office SFF will not fit a graphics card. Check the case before you buy the card, not after.
Power supply 550W+ from a brand you've heard of $70 The one part not to buy used. Cheap supplies fail in ways that take other components with them.
Storage 1TB NVMe SSD $60 Models accumulate faster than you expect.
Roughly~$770–900Leaves room for shipping and a case fan

What it does: a 7B model about ten times faster than you read, and a four-page document absorbed in about a second. This is where a local model stops being a demo and starts being a tool. If you take one thing from this page: this is the tier to buy.

Honest caveat on that $289: I measured an 8GB laptop card, not this one. A used desktop 3060 12GB has both more VRAM and more memory bandwidth on paper than the card I tested, so I'd expect the numbers above to be the floor rather than the ceiling — but I haven't measured one, so that's a reasoned expectation and not a benchmark, and I'd rather label it than quietly let you assume otherwise. Used price checked 24 July 2026.

~$1,800 — the 24GB tier, with no benchmark attached

The next real step is a 24GB card — a used RTX 3090 was averaging about $1,255 when I checked on 24 July 2026 — in a similar host, which lands the build near $1,800. 24GB holds a 14B model comfortably and a 32B model at a squeeze.

I don't own this card, so there is no number here Every other figure on this page came off a machine in my house. I don't have a 24GB card, so I'm not printing a tokens-per-second number for one — not from a forum post, not from a vendor chart, not from arithmetic dressed up as a measurement. What I can show you is the cliff you'd be paying to avoid, because that I did measure, on the 8GB card I do own. It's the first entry under "what broke".

Buy this tier only once you know the 7B models on the $900 box aren't smart enough for your specific job. That's something you learn by owning the $900 box for a month — not by reading a table.

Four things that broke when I did this

All four happened on the machines above, this week, while producing the tables you just read.

1. The 8GB card was already full, and the model simply refused to load

Box A has an RTX 3070 with 8GB. A 7B model needs about 5GB. That should be comfortable — except the card was already holding roughly 3.6GB for other things I run: a search index, a video job, a remote-desktop host. Free VRAM was about 4.2GB, and the load died on its face:

ggml_backend_cuda_buffer_type_alloc_buffer: allocating 4168.09 MiB
  on device 0: cudaMalloc failed: out of memory
llama_model_load: error loading model: unable to allocate CUDA0 buffer
Error: llama runner process has terminated

That's what the expensive tier really buys: not speed, headroom. VRAM is the one resource where running out isn't slow, it's a wall. Count what's already on the card before you blame the model:

nvidia-smi --query-compute-apps=pid,used_memory,name --format=csv

Fix: count free VRAM, not total VRAM — and count it with everything else running.

2. When it doesn't fit, Ollama doesn't warn you — it just gets slow

Force every layer onto the card and a model that doesn't fit fails loudly, which is honestly the kinder outcome. Left to itself, Ollama quietly splits the model between the graphics card and the CPU and carries on. Nothing errors, nothing warns. You get a fraction of the speed with no explanation, and if you'd never seen the fast version you'd assume that was just how it is.

Here's Box A doing it to me while I was writing this, with a 7B that had nowhere near enough room left:

$ ollama ps
NAME          ID              SIZE      PROCESSOR          CONTEXT
qwen2.5:7b    845dbda0ea48    5.4 GB    36%/64% CPU/GPU    4096

Thirty-six percent of that model was running on the CPU. Nothing in the interface says so. The PROCESSOR column is the only place it's written down, and what you want to see there is 100% GPU and nothing else.

Fix: check ollama ps after loading. Anything but 100% GPU means you're paying for a card you aren't using.

3. Generation speed is the wrong number, and I nearly published it alone

My first draft of the table above had one column: tokens per second, generating. By that measure the CPU tier looks tolerable — 9.5 tok/s, comfortably above reading speed, fine. Then I fed both configurations a real document instead of a one-line question and the CPU tier fell apart in a way the generation number completely hides: 59 seconds of silence against one second. Reading is where the CPU dies, not writing.

Nearly every local-AI benchmark you'll find quotes generation speed only. It's the metric that makes cheap hardware look best, which is presumably why.

Fix: benchmark with a long prompt, not a short one. Time the silence, not the typing.

4. Two hours of my benchmarks were quietly worthless

Halfway through, a completely unrelated job on the same desktop started sending its own work to the same Ollama server — hundreds of requests, on the same graphics card, on the same CPU. My numbers didn't error. They just drifted: the same 3B model measured 9.2 tok/s before it started and 8.3 tok/s after, and I'd have published the second figure without blinking if I hadn't gone looking at the server log and found somebody else's traffic in it.

# who else is talking to your model server?
journalctl -u ollama --since "-1 hour" | grep -c "api/"

Everything on this page was re-measured on a machine with nothing else running. The contaminated numbers are in the bin, which is the only honest place for them.

Fix: benchmark on a quiet machine, and check the log to prove it was quiet.

Should you actually do this?

Yes, if

  • There's work you can't send to a cloud model — private, medical, financial, or your employer's
  • You want to run something across thousands of items, where per-call pricing would stop you before you started
  • You'd value it still being there in ten years, unchanged, with the internet off
  • You can spend $900 rather than $400. The cheap tier teaches you the shape of the thing; the middle tier is the one you keep.

No, if

  • You want frontier-model quality. You'll be disappointed, quickly.
  • You're doing it to save $20/month — that's a twenty-month payback on a less capable product
  • Your plan is to run it on a laptop you also need for other things
  • You'd buy the $400 tier expecting conversation. Read the 59-second row again first.

One more piece of honesty about scope: these are the models I had pulled and could benchmark this week, not the survivors of a search for the best model available. Model rankings turn over every few months. The hardware conclusions — bandwidth, VRAM, and the reading wall — age far more slowly than the model names do.

Or I'll set it up for you — $199

You buy the hardware and own it outright. I configure it over a screen share, benchmark it in front of you with the same script that produced this page, and hand it over working.

  • Ollama installed and running as a service, models pulled and pinned so the first question of the day isn't slow
  • Placement confirmed at 100% GPU — not silently split with the CPU
  • A web chat interface on your own network, for everyone in the house
  • Tailscale remote access, zero ports forwarded to the internet
  • Your machine's own numbers, benchmarked in front of you, so you know what you bought
  • A plain-English runbook and two weeks of email support
← back to homegrown.computer