A 10 year old Xeon is all you need
If we just take into account output token generation for simplicity. With 5tps u get 18k tokens an hour. That would costs around 0.005USD from an inference provider.
I estimate that the server consumes probably around 500W during inference.
In Germany where 1kwh cost around 0.3USD, 18k tokens inferred locally would therefore cost 0.15USD which is 30x the costs of using an inference provider.
But for ppl who worry about their data, running locally might still be good. However, they should be aware, that it is much less efficient than using an inference provider.
The efficiency gap will also significantly increase as new GPUs will make inference much more efficient.
EDIT: I first thought it'd be 180k token, but thanks to someone mentioning in the comments, it is 18k. I guess with that, it will be tough unless u got electricity almost for free. Also, the inference providers are probably still using H200/H100 for those small models. Once they use GB300 or next year the new Ruby GPUs, inference will be cheaper by a factor of 30. By then, running local models will mostly be about privacy.
I am running Qwen3.6-35B-A3B locally on my 16GB mac with 7-9 tokens/second. Link - https://github.com/deepanwadhwa/samosa-chat
This is a GPT4 level model running locally with a decent speed on a 16gb ram macbook air.
https://gist.github.com/hparadiz/f3596d00a62d8ebb2dadcc46ee5...
At national average electricity prices, that’s $1.35 per day. More during the summer if you have to cool the space.
If you run it 24/7 and ignore prompt processing time (not a good assumption at all) it would get around 400,000 tokens in a day.
That’s about $0.30 per million output tokens.
Coincidentally, that’s the same price for this model on OpenRouter right now, but OpenRouter token gen will be 8X faster.
There are a lot of good reasons to experiment with running LLMs locally, like if you don’t want any data leaving your house.
Don’t think that you’re going to come out ahead monetarily. I say this as someone with a lot more money invested in local inference hardware at home. It’s fun, but it’s not a way to save money.
Android studio connected to a local model disconnects automatically after 10 minutes. How set this limit to 12 hours or remove it completely?
I could run my LM studio model all night... but I cant, since Android studio times out after a hard limit of 10M.
This is not related to number of tokens.
I tried Googling, searching for settings in Android studio, even created a stackoverflow post - but zero information. Jetbrains mentions "remote agent timeout mechanism" - but after changing it, nothing happens.
FWIW I'm getting a hardware max of 20 tok/s (approx topping out the GPU's compute) on my custom local diffusiongemma port running on an M3.
The fix is open upstream as PR #2138 (https://github.com/ikawrakow/ik_llama.cpp/pull/2138), awaiting review. Fair warning on the AI angle: the patch was written by Claude at my direction. The post is explicit about which parts were me and which weren't. Happy to answer questions about either the bug or the workflow.
In an hour it can process 3.6 million tokens or generate 144000 tokens. This costs me about 15 cents given my electricity prices.
For sonnet the equivalent token costs are 7.2 dollars for the prompt processing or 1.4 dollars for the generation. The cloud is 10x more expensive for generation and close to 50 times more expensive for processing.
Maybe, but for how long? Prices keep going up, and every new model eats more and more tokens...
I'm excited to get my mitts on it on Friday when it finally arrives.
Here's some of the resources I came across if you're interested in reading.
https://echalupa.com/blog/mac-pro-6-1-llama-cpp-firepro-d300...
https://matthewgribben.com/blog/mac-pro-6-1-llama-cpp-firepr...
Whether the writer's setup affects that choice I don't know.
It's quite telling you didn't use Qwen3.6-35B-A3B locally to build that, seems there was another collaborator ;)
Show something you've built with the model+tooling instead, truly dogfood it. I'm sure you'll discover things along the way too!
This prediction alone isn’t useful at all without a bound on speed and maybe quantization.
You can already run >200B MoE models on basic consumer hardware by picking a low bpw quantization and then streaming the experts from SSD. There have been a lot of proof of concept demos, but nobody uses them because they’re so slow and the quality is so degraded.
If you’re saying that hardware will catch up by mid-2027, I disagree. The limitation is fast memory and that’s going to be expensive for a while. I have a 128GB unified memory machine that can technically run 200B MoE models with enough quantization, but it’s so slow that there’s no reason to do it. It’s going to be a few years before we have enough RAM and processing power in basic consumer hardware without spending as much as a used car to get it.
> This is a GPT4 level model running locally with a decent speed on a 16gb ram macbook air.
Sorry, but 9 tokens per second with a slow prompt processing speed is not decent for anything other than getting short chat responses.
You’re also not running the full GPT4 quality model. I’m very familiar with that model from some other work and the 4-bit quants are just not as good as all of those KL divergence plots would have you believe.
You also have very short context. It’s basically useless for anything more than short chats where you’re okay watching the output come back at reading speed, skipping the reasoning part (which is important for calling it GPT4 level quality), and waiting a long time for the first token.
Yes, it’s technically running, but not in a way that would be useful by normal LLM standards.
It is debatable if we will actually need that many parameters though, since recursive nets like HRM (https://huggingface.co/sapientinc/HRM-Text-1B) don't need to parametrize as heavily.
I am curious about the decision to not use GPU since this is for Apple Silicon.
Wouldn't the GPU potentially accelerate the DeltaNet/attention layers and matrix multiplication in general?
But you said 7-9 tokens/second, that's not a decent speed. I'm not an expert by all means but in my local experiments, less than 12 to 16 tps is too slow.
https://docs.ollama.com/faq#how-do-i-keep-a-model-loaded-in-...
You didn't specify what was serving your local model.
What are the LLM standards?
Do you know how many people use perplexity? I know many people who are not software engineers or tech workers and have a LLM subscription for rewriting their stuff (non-native english speakers) in english. There are many use cases for running good models locally. Maybe not for you, but someone might find this beneficial.
Pending any new hardware or radically different LLM architectures, we're going to be waiting a lot longer than 2027 for 200B models on local hardware. SOC platforms like Apple Silicon are hamstrung by their obsession over raster performance, the hardware lacks the fundamental GPGPU hardware to be a replacement for real-world inference.
Instead of coding agents like tool for local models I would like to see more "docker ps" like tools where you can queue up tasks that get processes incrementally (maybe when the pc i idle) and are specialized for doing retries and caching as much work as possible to work decently with slow local models.
https://mikeveerman.github.io/tokenspeed/?rate=10&mode=text
You think of an idea that you want to have the LLM process, queue it up, and go back to what you were doing. Once you've finished reading the next article on HN about a 5 tps Xeon, your task will be complete. It's kind of like using a 3D printer: It doesn't matter if a print takes 10 hours, because when you come back in the morning it will be done.
Yes, with top-tier GPU farms you can hit hundreds of tokens per second. But if the old Xeon in the closet can get useful work done at 5 tokens per second, there are lots of people and lots of use cases where a free, unlimited 5 TPS stream is worth more than paying a dollars per day to get access to a 500 TPS source.
that would have run into a race condition unfortunately ;)
but there is a sample landing page + a python function on the repo which shows what the model produced. my goal is to integrate the local model in my workflow so that claude/OAI can call this model for basic stuff.
It will be feasible for everyone to have 20 different agents running at all times. A new world is coming
I don't think the post itself reads like AI at all, but that's just me.
I was responding to a lot of the comments saying this was a reasonable way to avoid paying for tokens or subscriptions. I don’t want anyone getting the wrong idea that this is a way to save money if that’s their priority.
Do you know how to switch it in LM studio?
What I see is that: android studio gives "Error: stream failed" and in LM studio server I see it is still working, then says that client (=android studio) disconnected.
So I assumed it was a setting in android studio.
Not really, you start small, bootstrap as soon as you can, and off you go. Requires a good model though ;)
It is common for agents to just stop because overload or some API error hijinks.
Or you get a TUI question that is blocking.
In general you’re right though, staring at tokens from agentic is not time well spent.
Some of these I’ve built custom harness around in iterm2 though.
I watch tokens to see if it goes in right direction. If model goes off the rails, then it is time to stop and adjust prompt.
If I spend 10 minutes reading an article, that would only generate 3000 tokens.
That’s not counting the prompt processing time.
We have very different expectations for LLMs if your tasks only take a couple thousand tokens and you’re happy waiting 10 minutes for it.
> Yes, with top-tier GPU farms you can hit hundreds of tokens per second
My 5090 gets hundreds of tokens per second with this model. No farm needed. I’d have to double check but I think even a $1000 Intel B70 might break 100 tokens per second.
> But if the old Xeon in the closet can get useful work done at 5 tokens per second, there are lots of people and lots of use cases where a free, unlimited 5 TPS stream is worth more than paying a dollars per day to get access to a 500 TPS source.
If that old Xeon pulls 200W from the wall and you pay national average electricity costs, it’s going to cost $0.90 per day to run it.
I would rather pay a dollar per day, get my answers 100X faster, and not have an old Xeon heating up my house.
Glancing through the docs, I would be digging down in the config of both Android studio and lm studio for either a TTL or jit auto evict setting, and if you find it, set it to some large number measured in hours?
https://developer.android.com/studio/gemini/use-a-local-mode...
What does it make clear? That I can replace the space heater my wife runs 9 out of 12 months of the year with a home server? And effectively get $0.00 per token during those times?
In houses running A/C year round, sure there'd be some impact, but in all the places running heat, doesn't seem that it'd move the needle on power bills.
There are startups whose entire business model is "cloud server as a home space heater" (aka "data furnace") ...
Let LLMs write the corpo code, as it will be unlikely to still be running in 5-10 years. Frontier AI is already at the point where it writes fewer bugs per LOC than humans. By a lot.
Go ahead and do your bespoke coding on your side-project loves and core libraries... The stuff that will last, anyway.
But if you're working for a corpo and still doing bespoke... That's... not gonna last, I'm afraid. Well, either you remaining there, or that, as it were.
Keep your mental context in your brain is critical
It says so right in the readme. They’re not hiding anything.
That it’s pulling a lot of watts.
Good for you if it’s replacing electric space heaters.
There’s a server in my basement that has no business running a modern language model. It’s a repurposed HP StoreVirtual storage box, roughly thirteen years old, two Ivy Bridge Xeons, no GPU. It was built to hold disks, not do math. As of this week it runs Google’s Gemma 4, a 26-billion-parameter open-weights mixture-of-experts model, at about five tokens per second. Reading speed.
| Hardware | Repurposed HP StoreVirtual: dual Xeon E5-2690 v2 (Ivy Bridge, 2013), DDR3, no GPU |
| Instruction sets | AVX1 only — no AVX2, no FMA3 |
| Model | Gemma 4 26B-A4B (MoE), Q8_0 |
| Decode | ~5.2 tokens/sec |
| Prompt eval | ~16 tokens/sec |
| Cost of the box | under $300 |
Anybody can rent a GPU. It’s harder to take a modern MoE model and a dead enterprise box and make them meet in the middle, and that gap is the whole reason I’m writing this up. “Good with AI” has quietly come to mean “pays for a subscription.” I think the real skill is different: knowing a model well enough to point it at a problem nobody packaged for you, and telling whether the answer it hands back is actually correct. So rather than claim we’re good at this, here’s a worked example, on hardware that had no business cooperating.
A couple of weeks ago a piece called “A 10 year old Xeon is all you need” made the rounds on Hacker News. The author runs Gemma 4 on a single 2016 Xeon with no GPU and 128 GB of slow DDR3, using ik_llama.cpp and about 25 carefully chosen flags. It’s a great read, and it leans on every trick in the modern inference playbook: speculative decoding, CPU-aware mixture-of-experts routing, flash attention ported to the CPU, run-time weight repacking. Real engineering.
“I have a Xeon too,” I thought. Several, in fact. So I tried it. It didn’t run.
The build died on startup. I handed the failure to Claude and asked what was wrong. The answer came back fast and specific. The author’s 2016 chip is a Broadwell part. Mine are Ivy Bridge, the generation Intel calls “v2.” The fast kernels in that fork assume AVX2 and FMA3, instruction sets that didn’t ship until Haswell, the “v3” generation, in 2014. My CPUs are older than the instructions the code was written against. The optimized paths weren’t there to execute.
So I asked the obvious follow-up: can we make it run anyway? I’d already taken a first swing with a free model that got close but couldn’t land it. Claude picked up that half-finished approach, agreed it was the right one, and finished it off, reworking the hot paths so they fall back cleanly on a pre-AVX2 chip instead of reaching for instructions that aren’t there.
This is the part I care about. This didn’t come from typing “fix it” once and getting a working patch back. Somebody had to read another person’s performance-critical C++, work out why a kernel wasn’t valid on this particular microarchitecture, and route around it without throwing away the optimizations that made the fork worth using. Claude did that work. My job was narrower: run the right experiments and recognize when the output was finally correct. I came away impressed.
Gemma 4’s 26B mixture-of-experts model now generates text at reading speed on hardware that was retired before the model’s architecture existed. The original write-up never published a tokens-per-second figure, just “reading speed,” so here’s the concrete one: about five tokens a second on thirteen-year-old silicon, for borderline free.
Proof it runs: Gemma 4 26B answering on the basement box, CPU-only.
The patch is up as ikawrakow/ik_llama.cpp#2138 if you want the exact diff — still open and awaiting maintainer review as I write this, so run it from the branch for now. The hope is that anyone else sitting on ancient enterprise iron can keep a local model around: a fallback for when the paid APIs are down, or a cheap way to grind through slow batch jobs when paying per token doesn’t make sense.
Full disclosure before I go further. I’m not a C++ programmer. I can read a stack trace and I know my way around a build system, but I did not hand-write kernel fallbacks for a quantized matmul engine, and I won’t pretend I did. What I did was drive. I ran the experiments, read the output, asked the next question, and knew what “correct” had to look like. The diagnosis and the patch came from the Claude instance running on the server itself. I asked it to write up what it fixed, and the rest of this section is that summary, lightly edited. If you came here from Hacker News for the real teardown, this part’s for you.
The engine we needed was ik_llama.cpp, ikawrakow’s fork of llama.cpp that adds the optimizations Gemma 4’s MoE inference depends on. It assumes AVX2 as its floor. The Xeon E5-2690 v2 in this box has AVX1 but not AVX2. Turn GGML_USE_IQK_MULMAT off at build time and most of the codebase respects it: the fast paths compile out, and the model falls back to plain scalar/SSE math. That’s fine for a normal Q8_0 matmul.
Two graph ops are the exception. The Gemma 4 MoE feed-forward network emits MOE_FUSED_UP_GATE (a per-expert gate+up matmul fused with SwiGLU) and FUSED_UP_GATE (its dense analog). Both are #if-gated on GGML_USE_IQK_MULMAT inside the compute dispatcher, but the graph builder still emits them unconditionally. On this build the dispatcher’s switch had no case for those op enums, so they fell through to the default, and the destination tensors for every expert FFN silently never got computed. Gemma 4 26B has 30 layers by 8 active experts per token, so every forward pass consumed roughly 240 tensors of whatever happened to be sitting in that memory buffer already.
The symptom was fluent-looking multilingual gibberish. Token IDs spread uniformly across the 262K vocabulary, the model equally happy to emit Thai script, Korean, <unused> sentinels, or English fragments. Deterministic at temperature 0, byte-identical between single- and multi-threaded runs, no NaNs anywhere. Just a hidden state getting shoved by a large constant every layer until the final softmax went flat.
That determinism is what cracked it. Claude instrumented the raw logits before sampling, printing the top-5 tokens plus range, mean, and NaN count. The numbers gave it away: a mean logit of +16 for the first predicted token when it should sit near zero, and about 80% of the vocabulary at positive logits. Random corruption doesn’t look like that. A bias that clean only happens when a big chunk of the hidden state is uninitialized memory that happens to hold small positive floats.
Three commits on top of the fork’s main.
Compile fixes. The scalar #else branches for quantize_row_q8_0_x4 and quantize_row_q8_1_x4_T in iqk_quantize.cpp weren’t actually scalar. They still referenced hsum_i32_8 and other AVX2 helpers. Those got rewritten as portable scalar loops, with #if GGML_USE_IQK_MULMAT guards added around a handful of stray IQK calls leaking through ggml.c and ggml-quants.c, plus a missing include so iqk_cpu_ops.cpp compiles standalone. Without these, the fork won’t build at all on non-AVX2 hardware.
The runtime bug. Rather than touch the dispatcher, the fix makes the graph builder emit ops that do have compute paths on this build. In ggml_moe_up_gate, when GGML_USE_IQK_MULMAT is off: if the weight is the combined up_gate_exps tensor (shape [n_embd, 2*n_ff, n_experts], gate in the first half, up in the second), split it into two ggml_view_3d slices, run two separate ggml_mul_mat_id calls, and combine them with ggml_fused_mul_unary(gate, up, SILU). If gate and up are already separate weights, skip the split and do the same two mul-mat-IDs plus the fused mul-unary. ggml_fused_up_gate, the dense version used in non-MoE layers, gets the same treatment. Every op involved already has a working non-IQK implementation (mul_mat_id is stock ggml, and fused_mul_unary does the SILU-and-multiply in one pass). The whole change sits behind #if !GGML_USE_IQK_MULMAT, so an AVX2 build stays bit-identical to what it was before.
CI stubs. The #else stub sections of the iqk sources had drifted out of sync with iqk_mul_mat.h, so ci/run.sh couldn’t even build on non-AVX2 hardware: a missing <cstdint>, stubs with the wrong signatures (an extra leading parameter here, a missing sinks there), and no stubs at all for a couple of functions, which meant undefined references at link time. Boring work, but without it nobody on this hardware can run the test suite.
The fallback costs something, two separate matmul-IDs instead of one fused kernel, but this CPU is memory-bandwidth-bound anyway, and the fused kernel was AVX2-only, so we weren’t giving anything up. End to end we get about 5.2 tok/s decode and ~16 tok/s prompt-eval on a 26B-A4B MoE.
One more gotcha. --run-time-repack reorders quantized weights into an AVX2-only interleaved layout (Q8_0_R8) at startup, which garbles output on AVX1 the same way. That’s a separate bug, and the patch doesn’t try to fix it. The run script just drops the flag.
The instruction-set mismatch was easy to spot. The silent fall-through was not. Reading the code kept clearing the obvious suspects: the RMSNorm helpers looked correct, the AVX1 fallback in ggml_vec_dot_q8_0_q8_0 looked correct, and a bit-identical single-thread run ruled out threading. Only after instrumenting the logits, and seeing the mean pinned at +16 with every long-tail token roughly tied, did the search narrow to “a big chunk of the residual stream is uninitialized.” Grepping for #if GGML_USE_IQK_MULMAT in the dispatcher turned up the two missing cases about a minute later.
If you have a pre-AVX2 box and want to try this:
ik_llama.cpp from the branch above with GGML_USE_IQK_MULMAT off. The compile fixes are what let it build at all on non-AVX2 hardware.Q8_0.ik_llama.cpp CPU flags, but drop --run-time-repack (it reorders weights into an AVX2-only layout and re-garbles the output on AVX1).That is the whole recipe: about 5 tok/s decode, CPU-only, no GPU anywhere in the box.
The subscription is the easy part. The rest is the willingness to open the hood, read a stranger’s code, and keep asking until a thirteen-year-old CPU does something it was never meant to. That’s the same work a fifteen-year-old Rails app needs, or a database nobody left on the team still understands: someone who’ll dig until they find where the leverage is, and what the tool won’t tell you on its own.
If you have pre-AVX2 iron gathering dust and try the branch, I’d love to hear what it does on your silicon — how far down the CPU generations does this go? The PR thread is the right place for bug reports. And if the thing you’re nursing along is a fifteen-year-old Rails app rather than a thirteen-year-old Xeon, that’s what we do for a living.
A couple of pointers for the curious. The server itself cost under $300; here’s the math on why a basement box beats $1,500 a month of cloud. And getting a screaming enterprise appliance quiet and bootable in the first place was its own project, written up here for people who enjoy that sort of thing.
At 5 tokens per second and unknown prompt processing speed, you may need a very extra long lunch break depending on your codebase.
This is an option if you must run local inference, you’re not sensitive to speed, and the budget is low.
It’s not going to be cheaper than paying API prices for the model though.
These are fundamentally different tools for entirely different applications. They only look similar to people who don't understand the tools or their purpose.