Running a 35B local LLM on a laptop's integrated GPU with 64 GB of shared memory

A 35-billion-parameter mixture-of-experts model and a 27-billion-parameter dense one are run on the integrated Radeon 860M of a ThinkPad with 64 GB of LPDDR5X, through Ollama and, on the same hard-linked weights, LM Studio. The piece explains why an integrated GPU's capacity is the system RAM and its speed is that RAM's bandwidth, measures both models on the GPU and on the CPU, and records a conclusion that had to be withdrawn after three measurement errors. It ends with the decision not to reserve dedicated video memory, a Claude Code hookup over MCP, a priced answer on whether the 64 GB were worth it and what memory prices are doing in 2026.


The laptop is a Lenovo ThinkPad with an AMD Ryzen AI 7 PRO 450, whose integrated Radeon 860M is the only GPU in the machine, and 64 GB of LPDDR5X soldered to the board. I wanted a language model running on it that was good enough to summarise, extract and draft, offline, and that Claude Code could hand work to. It took one day, 21 October 2026, and ended as a small public repository, apu-llm: one line installs everything on Windows, and a command called apu asks the model things, measures it and serves it to Claude Code.

The model that stayed is Qwen3.6 35B-A3B, 35 billion parameters of which about 3 billion work on each token. It writes 11.7 tokens a second on the integrated GPU, reads a long prompt at 93, and leaves 11 or 12 GB free with a browser and an editor open. The way there had a measurement I got wrong, committed as a finding and withdrew 37 minutes later, and that error says more about benchmarking this kind of machine than the final table does. Every number below comes from the repository's journal and the benchmark files it keeps.

The name26 · oct 21Read noteI went through thinkpad-local-llm, unified-memory-llm and ryzen-ai-llm before apu-llm. The ThinkPad is incidental: any laptop with this kind of chip works the same way. Unified memory is the word Apple uses, and Macs have their own tools; this is a Windows repo. Ryzen AI ties it to AMD, when an Intel Core Ultra should take the same Vulkan path. APU is AMD's word too, I know, but it names the thing that matters, a CPU and a GPU sharing one memory.

Why the integrated GPU has no memory of its own

A graphics card in a desktop has its own memory chips on its own board, GDDR7 on a current NVIDIA card, wired to the GPU over a wide bus and to nothing else. An integrated GPU sits on the same piece of silicon as the CPU cores and has no chips of its own. It reads and writes the same LPDDR5X the CPU uses. The firmware sets aside a small fixed slice of that RAM at boot (here 512 MB, the BIOS default, which is what Windows reports as the GPU's dedicated memory), and everything else the GPU needs is borrowed from the rest of the RAM on demand, through the GPU's own address translation, as shared memory.

That arrangement splits the two questions a local model raises. Whether a model fits is a question of capacity, and on this laptop the GPU's capacity is a large share of 64 GB, more than the 32 GB of the largest consumer NVIDIA card. How fast it runs is a question of memory bandwidth, and there the integrated GPU is far behind. The memory is four chips on a 128-bit bus at 8000 transfers a second, so at most 16 bytes times 8000 million, 128 GB/s, have to serve the CPU and the GPU together. An RTX 5090 has 1,792 GB/s for itself1.

1NVIDIA, Compare GeForce graphics cards, memory bandwidth of the RTX 5090 (32 GB GDDR7) and RTX 5080 (16 GB GDDR7, 960 GB/s).

The bandwidth matters because of how a model writes. Each new token is one pass through the network (a decoding step), and that pass multiplies the token's activations by every weight matrix the token goes through. The arithmetic is small, a couple of operations per weight, while every one of those weights has to travel from RAM to the processor. Generation is therefore memory-bound: the time per token is roughly the bytes of weights read divided by the bandwidth, and the compute units wait. With weights stored at about 4.8 bits each (quantization to the Q4_K_M format), a model's bytes per token are its active parameters times 0.6 bytes.

This is where the kind of model decides everything. A dense model sends every token through all of its weights. A mixture of experts replaces each layer's feed-forward block with many small blocks and a router that picks a few per token: Qwen3.6 35B-A3B has 256 experts and activates 8 of them plus a shared one, so about 3 of its 35 billion parameters work on any token1. All 35 billion still have to be in memory, because the next token may want different experts, but only about 2 GB are read for each one.

1Qwen, Qwen3.6-35B-A3B model card, Hugging Face, April 2026: 35B total, 3B activated, 256 experts, 8 routed and 1 shared active per token, Apache 2.0.

## The machine Memory64 GB LPDDR5X-80004 × 16 GB, soldered, 63.1 GB visible to Windows Bus128 bits Theoretical bandwidth128 GB/sshared by CPU and GPU Dedicated GPU memory512 MBBIOS default ## Bytes read per token, Q4_K_M Qwen3.6 35B-A3B~2 GB~3B active parameters Qwen3.8 27B~16 GBdense, every weight ## Ceiling from bandwidth alone Qwen3.6 35B-A3B~64 tok/s Qwen3.8 27B~8 tok/s

The ceilings are what a perfect memory system would allow, and no real one gets there. Reading a prompt is a different workload: the engine pushes hundreds of prompt tokens through each weight while it has it, so the cost moves from moving bytes to doing arithmetic, and that is where a GPU's many parallel units should pay. Writing should be close to a tie between CPU and GPU, since both drink from the same memory, and reading should favour the GPU. That prediction is what the measurements below eventually confirmed, after first appearing to contradict it.

Ollama skips the GPU it can see

Ollama 0.40.7 went in with winget install Ollama.Ollama. Its window opens on an optional account screen, which local use does not need, and then lists integrations that launch coding agents, Claude Code among them, against a local model.

Ollama's first screen. The account is for the faster, larger models Ollama hosts; the link under the button skips it.The integrations page that follows: each entry launches an agent against a model Ollama serves.

The first model ran on the CPU, which the app does not show and the server log does. GPU discovery rejected the Radeon twice, for two different reasons:

TEXT Copy

level=WARN msg="dropping ROCm device — no rocblas support for gfx target" gfx_target=gfx1152 supported="map[gfx1030:true gfx1100:true ... gfx1150:true gfx1151:true gfx1200:true ...]" level=INFO msg="dropping integrated GPU; to enable, set OLLAMA_IGPU_ENABLE=1" library=Vulkan description="AMD Radeon(TM) 860M Graphics" level=INFO msg="inference compute" id=cpu library=cpu total="63.1 GiB" available="30.3 GiB" level=INFO msg="vram-based default context" total_vram="0 B" default_num_ctx=4096

ROCm, AMD's compute stack, identifies each GPU by its instruction-set target, and the 860M is gfx1152. Ollama's bundled ROCm libraries are built for gfx1150 and gfx1151 (the 890M and the Ryzen AI Max) and not for this one, so ROCm drops it. Vulkan, the graphics API that also runs compute shaders, finds the GPU and works with it, and Ollama then drops it on purpose because it is integrated. The fix is the variable the log names, OLLAMA_IGPU_ENABLE=1, set for the user. After a restart:

TEXT Copy

level=INFO msg="inference compute" library=Vulkan description="AMD Radeon(TM) 860M Graphics" type=iGPU total="47.6 GiB" available="45.3 GiB" level=INFO msg="vram-based default context" total_vram="47.6 GiB" default_num_ctx=262144

The last line is a side effect worth catching. Ollama sizes its default context from the video memory it believes it has, and with 47.6 GiB it jumps from 4,096 tokens to 262,144. The KV cache for a quarter of a million tokens costs gigabytes before a single word is written, so apu asks for 16,384 tokens on every request instead. Discovery itself takes 20 to 30 seconds, long enough for the desktop app's readiness check to give up once and log ollama server not ready, continuing anyway; it recovers by itself.

The two models came down in parallel over home wifi at 7 to 9 MB/s combined, about an hour for 21 GB and 18 GB. One pull sat at 2% with no error while the file on disk already measured 20.2 GB. Ollama allocates the whole file before writing into it, so its size says nothing; the real progress is in the -partial-N JSON files beside it, and restarting the pull resumed where it stopped.

Two engines, one copy of the weights

LM Studio went in next (winget install ElementLabs.LMStudio, version 0.4.26), to check Ollama against something. The two are easy to confuse, because underneath they are close to the same program. Both are built on ggml, the tensor library of llama.cpp, and both read models in GGUF, llama.cpp's file format, which holds the quantized weights and the tokenizer in one file. For newer architectures Ollama has its own ggml-based engine, but for this model its API reports runner: llamacpp. On Qwen3.6 35B-A3B, then, both engines run llama.cpp on the same file; what differs is the packaging around it and the defaults.

Ollama stores each model as content-addressed blobs under ~/.ollama/models/blobs, and the largest blob of a model is the GGUF itself (it starts with the four bytes GGUF). Instead of downloading 40 GB a second time, I gave LM Studio a hard link to that blob: a second directory entry for the same bytes on disk, which costs no space and guarantees the two engines run byte-identical weights. LM Studio listed it as qwen3.6-35b-a3b, 35B, qwen35moe, 21.72 GB and loaded it with no conversion.

lms import moves the file by default.

Run on Ollama's blob, it would pull the GGUF out from under Ollama. lms import --hard-link (-L) adds a second name instead; deleting the model in one engine leaves it intact in the other. A hard link needs both stores on the same NTFS volume and, unlike a symbolic link on Windows, no administrator rights.

LM Studio's first run offers a starter model, Google's Gemma 4 E4B at 6.33 GB, which I skipped, and then two advanced settings: Developer Mode, off, which hides the engine, GPU offload and server options, and a local service started at login, on. I turned the first on and the second off. Ollama is the engine that stays resident, and two servers loaded from boot would each hold memory for nothing.

LM Studio's first-run offer: Gemma 4 E4B, 7.9B parameters in total, 6.33 GB to download.The defaults as shipped: Developer Mode off, the service at login on. Both were flipped.

The difference that showed first is the one that cost Ollama the morning: LM Studio needs no switch for the integrated GPU. It ships CPU, CUDA and Vulkan builds of llama.cpp and picked the Vulkan one by itself. The second difference is stranger. Asked for the GPU's memory, lms runtime survey answered 31.76 GiB, where Ollama had reported 47.6 for the same chip:

TEXT Copy

AMD Radeon(TM) 860M Graphics (Vulkan, Integrated) 31.76 GiB RAM: 63.14 GiB

31.76 GiB is roughly half the RAM plus the 512 MB carve-out, which matches the shared GPU memory Windows offers an integrated GPU and shows in Task Manager. 47.6 GiB is about three quarters of the RAM. The two engines are reading different figures for the same memory pool, and only a model larger than 32 GB would tell which one the driver actually honours. Nothing that large was loaded, so the question stays open; both models used here fit under either ceiling.

Ollama

LM Studio

a background service with a CLI and a thin desktop app Shape a desktop app with a server and a CLI (lms) added

off until OLLAMA_IGPU_ENABLE=1 Integrated GPU on, Vulkan runtime chosen by itself

47.6 GiB GPU memory reported 31.76 GiB

after 5 minutes Idle unload after 1 hour (jitModelTTL)

55 s Cold load of this model 124 s

11.7 tok/s Writing, same weights 9.4 tok/s

93 tok/s Reading, same weights 83 tok/s

MIT Licence the lms CLI MIT, the app closed

In both File format: GGUF In both Tensor library: ggml

The licences are on GitHub: Ollama's repository and LM Studio's lms CLI are both under MIT1, while the LM Studio app itself is not open source. LM Studio also carries a loading guardrail that refuses models it estimates will not fit, which is one more reason its smaller memory figure matters to a user.

1ollama/ollama and lmstudio-ai/lms, both MIT; the LM Studio desktop app has no public repository.

Engine choice26 · oct 21Read noteOllama is the one that stays. On identical bytes it wrote 25% faster and read 12% faster, it is open source, it runs as a service I can script, and its API says how much of the model sits on the GPU. LM Studio's real advantage is that the GPU just works, which a setup script can give Ollama with one variable. I keep LM Studio installed as a second opinion: if a number from Ollama looks wrong, the same file through another wrapper is the quickest check.

The iGPU looked slower than the CPU

The first comparison used a small script, tools/compare_engines.py: the same weights and prompts through each engine, 256 tokens written for the writing speed, a 2,906-token prompt for the reading speed, temperature 0, thinking off, each engine's own timings so the network and the JSON stay out of it. It produced this:

Engine, device Writing (tok/s) Reading (tok/s)

LM Studio, Vulkan iGPU 7.1 62

Ollama, Vulkan iGPU 7.6 not comparable

Ollama, CPU only 11.3, 10.8 55, 52

The GPU was writing a third slower than the CPU on the same memory. It was clearly working (its compute engine sat near 48% busy, and Windows counted 23.4 GB of shared GPU memory in use), just slowly. 7 tokens a second at 2 GB per token is 14 GB/s, a ninth of the theoretical bandwidth, and I had a hypothesis ready that fit: on Windows, shared memory goes through the GPU's address translation and might be a slower path than the dedicated carve-out, although both are the same chips. There was even support for it. AMD's own tests report that reserving more dedicated memory adds 17 to 22% on small models1, and a llama.cpp issue describes a GPU with shared memory running slower than the CPU on Windows2. I wrote it up as a finding and committed it.

1AMD, Accelerating Llama.cpp Performance in Consumer LLM Applications with AMD Ryzen AI 300 Series, 30 October 2024: about 22% for Llama 3.2 1B on a 16 GB machine, up to 17% for Mistral Nemo 12B. 2llama.cpp issue #10330.

Then I looked at when each row had been taken, and the table fell apart three ways.

The GPU rows were measured while the second model was still downloading, with the network, the disk and the hash check all busy; the CPU rows came after the download finished.

Every prompt began with Run 1., Run 2., the same text in every invocation of the script, and Ollama keeps a prompt cache. A later invocation re-read the 2,908-token prompt at 7,000 to 9,000 tokens a second while still reporting all 2,908 as evaluated.

A request with default options reused a model still loaded with num_gpu: 0 from the CPU test. A run labelled GPU was 0% on the GPU, and only /api/ps (size_vram: 0) said so.

Each trap has its own fix, and all three are now in the script and in apu bench. A random nonce opens every prompt, so no engine can reuse a cache across runs. Before each configuration the model is unloaded (keep_alive: 0), and after it the engine is asked where the model actually sat; a requested placement is not proof of one. Nothing else runs during the measurement, apart from the browser and the editor that are always open. The clean run:

Ollama, Qwen3.6 35B-A3B Writing (tok/s) Reading (tok/s) Placement read back

Vulkan iGPU 11.7 (9.5, 11.7, 12.8) 93 (96, 93, 77) 20.6 GB, 100% GPU

CPU only 11.2 (11.6, 11.2, 10.5) 53 (54, 52, 53) 20.9 GB, 0% GPU

Writing is a tie within the spread of the runs, and reading a long prompt is 1.8 times faster on the GPU, which is what the mechanism predicted. 11.7 tokens a second at 2 GB each is about 23 GB/s of weight traffic, a fifth of the theoretical bandwidth, on both devices, so whatever holds generation back here is common to CPU and GPU and does not point at the shared-memory path. LM Studio under the same conditions, with the same hard-linked file, wrote 9.4 (7.8, 9.4, 9.7) and read 83 (84, 78, 83)1. It loads with four parallel slots by default, which may account for part of the gap; I did not isolate it.

1LM Studio's usage counter labelled every generated token as reasoning, although the script asked for thinking off. The speed per token does not depend on what the token says, so the comparison holds, but its thinking switch did not take through this API.

Withdrawn26 · oct 21Read noteThe wrong version is still in the repository's history, commit a04b954, titled as if it were true, and the journal keeps it as Finding 3 with a line saying it was withdrawn. I left it on purpose. The withdrawn table is the most useful thing the day produced for anyone benchmarking a shared-memory machine: every one of those traps looks like a hardware property until you check the timestamps.

A dense 27B model reads every weight

I downloaded a second model knowing it would be slow. Qwen3.8 27B scores 33.7 on the Artificial Analysis Intelligence Index against 18.2 for Qwen3.6 35B-A3B1, almost twice the score, and it is dense, so every token reads all of its roughly 16 GB.

1Artificial Analysis Intelligence Index, reasoning modes, as listed on BenchLM, updated 20 October 2026: Qwen3.8 27B 33.7, Qwen3.6 35B-A3B 18.2, Claude Opus 5.5 57.6, GPT-5.6 Sol 58.9.

Ollama, Qwen3.8 27B Writing (tok/s) Reading (tok/s) Placement read back

Vulkan iGPU 2.6 (2.3, 2.8) 13.8 (14, 14) 16.3 GB, 100% GPU

CPU only 2.2 (2.1, 2.3) 9.1 (9, 9) 17.0 GB, 0% GPU

A 256-token answer takes about 100 seconds, and a 2,900-token prompt takes three and a half minutes to read before the first word appears. The weight traffic is higher than the MoE's, about 42 GB/s, so the memory is better used by one large sequential read per matrix than by many small expert reads scattered across 35 billion parameters (a plausible reading of the two numbers that I did not test). The dense model still writes four and a half times slower, because each token carries eight times as much data.

What fits in 64 GB against the frontier, on the Artificial Analysis Intelligence Index (reasoning modes) as of 20 October 2026. The blue bars run on this laptop. GPT-5 high (August 2025) at 23 is Artificial Analysis's estimate, and index versions are not comparable across releases.

The chart puts the everyday model where it belongs, below the GPT-5 of August 2025 and a third of the way to the current frontier. It hallucinates when it does not know, and its answers need checking. Alibaba's own benchmarks put it ahead of its predecessor and of Gemma 4's MoE on agentic coding, which fits how it is used here, as a drafter whose work gets checked.

Alibaba's published scores for Qwen3.6-35B-A3B (darkest bars) against two MoE and two dense models of similar size: 73.4 on SWE-bench Verified, 86.0 on GPQA Diamond. Figure by Qwen (Alibaba), from the model card on Hugging Face.

Two models26 · oct 21Read noteSo the MoE is the default and the dense one waits for questions that are short and hard. At 2.6 tok/s a paragraph of answer is a minute, which is fine for one tricky question and useless for a document. Running only the 27B would have meant a smarter model I avoid using; running only the MoE would have meant no fallback when it is out of its depth. Disk is cheap, and only one of them is ever in memory.

The two tables give the figures the rest of the piece leans on:

11.7 tok/sQwen3.6 35B-A3B writing on the Radeon 860M, a tie with the CPU's 11.2clean run, 3 runs, median 1.8×how much faster the integrated GPU reads a long prompt than the CPU, 93 against 53 tok/ssame run 2.6 tok/sthe dense Qwen3.8 27B writing on the same GPU2 runs, median 20.6 GBQwen3.6 35B-A3B loaded, 100% on the GPU, context 16,384/api/ps after the run 10.9 to 12.7 GBRAM left free with that model loaded and the usual apps openapu stats, two readings

Not Gemma26 · oct 21Read noteLM Studio's first suggestion, Gemma 4 E4B, is a fine model for a 16 GB laptop, and the repo's installer gives it to machines with 14 to 27 GB. On 64 GB it would leave most of the memory idle to save time on answers that are already fast enough. I'd reach for it for bulk trivial work (thousands of one-line classifications), where speed per item is the whole game.

Why nothing is reserved for the GPU

The 512 MB carve-out can be raised. AMD calls the setting Variable Graphics Memory, and it sits in AMD Software under Performance and Tuning; it turns a chosen amount of RAM into dedicated video memory. What it cannot do is change while Windows runs. The carve-out is set by the firmware at boot, before the operating system exists, and Windows sees whatever is left as its RAM. Reserving memory means a reboot, and taking it back means another.

The withdrawn finding had been the reason to try it, and the clean run took most of the reason away. CPU and GPU write within 5% of each other, both at a fifth of the theoretical bandwidth, and the CPU does not go through the GPU's address translation at all. If shared memory were the bottleneck, the CPU would have pulled ahead. AMD's 17 to 22% were measured on 1B and 12B models, and the cost here would be permanent: reserving 24 GB for the GPU takes 24 GB from every other program whenever no model is loaded, which on this machine is most of the day.

No carve-out26 · oct 21Read noteI nearly did it, while the withdrawn table still looked true: AMD Software, 24 GB, reboot, rerun, reboot back if it did nothing. Once the clean run came in, two reboots for a few percent at best on a bottleneck the numbers didn't point to was not worth it. The repo says plainly that this is untested. If someone with the same chip tries it, apu bench writes a file I'd like to see.

Claude Code hands it work

The apu command talks to Ollama's native API (/api/chat, /api/ps) and writes timings to standard error and the answer to standard output, so apu ask ... > answer.md stays clean. Every request is logged to ~/.apu/log.jsonl, and apu stats summarises the log. The same code runs as an MCP server over standard input and output, registered once for every project:

POWERSHELL Copy

claude mcp add --scope user apu -- "$(Get-Command apu | % Source)" mcp

The absolute path matters, because a Claude Code session started before apu reached the PATH would not find the bare name. Claude Code then has two tools: local_llm_status, and local_llm_ask, which takes a prompt and a list of file paths. The server reads the files itself, so their content goes to the local model without passing through Claude's context. The tool's description is what tells Claude when to use it: offline, free and private, weaker than Claude, good for summarising, classifying, extracting, first drafts and anything that must not leave the machine, and to check its answer before relying on it.

Native API26 · oct 21Read noteOllama also speaks the OpenAI-compatible API, and using it would have made apu work with any engine. I picked the native one because it reports what I wanted to measure: load time, prompt time and generation time from inside the engine, and /api/ps saying how many bytes sit on the GPU. The third trap above is only visible through that last field.

The first delegated task came from a fresh headless session: have the local model summarise the repository's article notes in three bullets, in Spanish, and give its answer back unchanged with a one-line judgement. The model loaded in 29 seconds and wrote at 14.7 tokens a second. The answer, shortened, and Claude's review, translated:

Local modelEstablishes documentation requirements and clarifies the relationship between Ollama and LM Studio [...] Details the technical measurements on the reference machine (860M), contrasting GPU memory use (47.6 GiB in Ollama against 31.76 GiB in LM Studio), download times and generation performance under identical conditions. Justifies architecture decisions such as the choice of the repository apu-llam [...] and the economic benefit of having 64 GB of RAM in laptops for running large language models.

Stats228 tok at 14.7 tok/s · prompt 870 tok at 137 tok/s · load 29.2 s · total 51.0 s

ClaudeThe structure is good and covers the three parts of the file, but it has errors that make it unreliable without review. It says download times where the file talks about the time until the model is unloaded from memory for inactivity (5 min against 1 h). It presents generation speed as measured, when the file marks it as pending. It writes apu-llam instead of apu-llm. And it treats the 64 GB purchase as justified, when the file only raises it as an open question.

Four factual errors in a summary whose shape was right, and the stronger model caught all four. That is the division of labour the tool description asks for, and the run is the evidence that it works and that it is needed. The original Spanish transcript is in the repository, in docs/evidence/.

Why MCP26 · oct 21Read noteA line in CLAUDE.md saying run apu ask for bulk work would have worked in this repo and nowhere else, and Claude would have had to paste file contents into a shell command. As an MCP tool it shows up in every project with its own description of when to use it, takes paths instead of contents, and gets its own permission entry, so I can allow it without allowing Bash.

What the 64 GB bought

The laptop cost about 4,000 euros, and the 64 GB were a large part of why I chose that configuration. Whether it was worth it, for this use alone, has a narrower answer than either yes or no.

What the RAM buys here is room. With the usual session open (Chrome with about 49 processes, Cursor, Claude Code, Anki), Windows was already using 32 GB before any model loaded. With Qwen3.6 35B-A3B loaded on top, 10.9 to 12.7 GB stay free. A 32 GB configuration of the same machine could not hold this model next to that session; it would have to close things or drop to a smaller model, and the repo's installer gives machines with 28 to 47 GB the Gemma 4 26B-A4B, which scores 16.7 on the same index. The usage figure flatters the case a little, since Windows and Chrome take more memory when more is there.

Speed is another matter, and the fair comparison for it is a desktop GPU. An RTX 5090 has 32 GB of its own memory at fourteen times the laptop's bandwidth; it launched at $1,999 in January 20251, and in September 2026 the cheapest one listed in Germany cost over 5,000 euros2, more than this whole laptop, before the computer around it. It would hold the 20.6 GB model and run it far faster. It would not hold a model larger than 32 GB, which this laptop can at least attempt. The RTX 5080, at $999 and 16 GB, cannot hold this model whole and would split it with the CPU.

1NVIDIA, NVIDIA Blackwell GeForce RTX 50 Series Opens New World of AI Computer Graphics, press release, 6 January 2025: RTX 5090 $1,999, RTX 5080 $999. 2Hagedoorn, GeForce RTX 5090 Street Prices in EU Now Exceed €5,000, Guru3D, 14 September 2026, citing Geizhals listings and the GDDR7 and DRAM shortages.

Renting is cheaper again for anyone whose use is occasional. A RunPod pod with an RTX 5090 cost $0.69 an hour on the community cloud and $1.19 on the secure one, and an A100 80GB $1.791, which is what I paid the same day renting an A100 to fine-tune Stable Diffusion. At $1.19, four thousand dollars buy about 3,400 hours. A cloud GPU does not keep data on the machine, though, and it costs a setup every time, which are the two things a model answering in the background through Claude Code is for. For quality per euro, a frontier model's API beats both, by the index above, whenever the data may leave.

1RunPod, Pricing, page updated 8 October 2026.

So the honest accounting is narrow, and it is inference economics at the smallest scale. The 4,000 euros bought a laptop I needed anyway; the cost to set against this use is the price difference between the 32 and 64 GB configurations at the time of purchase, and that is the figure to look up. For that difference, the RAM buys a private, always-available drafter, somewhat below the GPT-5 of August 2025, that writes about as fast as a person reads. Anyone who wants a fast model or a frontier one is better served by a desktop card or an API.

Will it get cheaper

Memory and models are moving in opposite directions, and for a machine like this one they change different numbers.

Memory got much more expensive. Memory makers moved wafers to HBM, the stacked DRAM that feeds AI accelerators, and to server DRAM, and the rest of the market ran short. Counterpoint Research counted rises of about 50% in early 2025 and expected prices to roughly double by mid-20261. TrendForce then measured conventional DRAM contract prices up 93 to 98% in the first quarter of 2026 alone, and expected another 58 to 63% in the second2. Its forecast for the LPDDR4X and LPDDR5X used in phones and thin laptops, this laptop's memory, was a rise of about 90% in that first quarter, the steepest in their history3. The rises are slowing: 10 to 15% expected for the fourth quarter4.

1Robinson, Commodity memory prices set to double as fabs pivot to AI market, The Register, 19 November 2025, citing Counterpoint Research and TrendForce. 2TrendForce, Rapid Contract Price Surge Drives 1Q26 DRAM Industry Up 81% QoQ, 1 June 2026. 3TrendForce, Memory Price Outlook for 1Q26 Sharply Upgraded, 2 February 2026, which also projected PC DRAM up more than 100%. 4TechNews, AI 伺服器新增需求支撐 4Q26 記憶體合約價漲勢,消費端壓力未減, 30 September 2026, reporting TrendForce's forecast for conventional DRAM; it gives no percentage for mobile DRAM, only that its rise will be smaller than in the third quarter.

When it reverses is where the sources disagree. TrendForce expects server DRAM to keep rising every quarter through the second half of 20271. The Bloomsbury Intelligence and Security Institute sees prices elevated through 2027 and 2028, normalising only once new fabs reach volume, with an oversupply possible in 2028 or 2029 if AI demand cools2. Nobody I found expects cheap memory before 2028, and the date after that depends on a demand curve no one can see.

1TrendForce, Long-Term Agreements Cap Price Increases; Server DRAM Contract Prices Expected to Rise 13-18% QoQ in 3Q26, 9 July 2026. 2Mellor, Memory semiconductor supercycle set to run through 2028, Blocks and Files, 21 January 2026, quoting BISI, Micron and IDC.

For this laptop the question is moot in one direction: its LPDDR5X is soldered to the board, so the 64 GB are what it will have for its whole life, at whatever price memory reaches. A standard for replaceable LPDDR5X modules in notebooks exists (JEDEC's CAMM2, published in December 20231), but this machine does not use it.

1JEDEC, JEDEC Publishes New CAMM2 Memory Module Standard, press release of 5 December 2023 (JESD318), covering DDR5 and LPDDR5/5X modules for notebooks.

The models are moving the other way, and they move only one of the two numbers. Mixture of experts has spread to the open models people actually run: Qwen3.6 35B-A3B reads 3 billion parameters per token, and OpenAI's gpt-oss-120b has 117 billion parameters with 5.1 billion active, shipped already quantized to 4 bits (MXFP4) so that it fits on one 80 GB GPU, while gpt-oss-20b fits in 16 GB1. That cuts the bytes read per token, which is exactly what a bandwidth-poor machine like this one needs, and it is why a 35B model is usable here at all. The bytes that have to be held stay where they were, and a sparser model tends to be a larger one in total, so the gain shows up as speed on machines that already have the capacity. The capacity is the part whose price doubled. My guess, and it is only that, is that a 64 GB machine in two years runs a better model than this one at the same speed, and that the machine itself costs more to buy than this one did.

1OpenAI, gpt-oss-120b model card, Hugging Face, August 2025: 117B total and 5.1B active parameters, 21B and 3.6B for gpt-oss-20b, MXFP4 on the MoE weights.

Installing it

Everything above that had to be done by hand is in one line of PowerShell:

POWERSHELL Copy

irm https://raw.githubusercontent.com/yago-mendoza/apu-llm/main/install.ps1 | iex

The script installs Python with winget if it is missing (the Microsoft Store's python stub does not count, since it only opens the Store), installs apu with pip for the user, adds pip's user Scripts folder to the PATH, which pip does not do and which left apu unreachable the first time, and runs apu setup. That asks before each step: Ollama, the OLLAMA_IGPU_ENABLE switch, the model that fits the machine's RAM, and the Claude Code registration. Open Ollama afterwards from the Start menu; launched from a script, its desktop app did not bring the server up.

TEXT Copy

apu ask "question" ask the local model apu ask "fix this" -f app.py with files as context (-f repeats) cat log.txt | apu ask "why?" or piped input apu ask --think "hard one" let it reason first (slower, better) apu ping alive? which model, where loaded, how fast right now apu stats loaded model, free RAM, median speed of recent requests apu bench repeatable benchmark, saved with the machine's specs apu models / apu use <model> downloaded models / change the default apu doctor checks every piece, prints the fix for each failure

On the reference machine apu doctor passed all eight of its checks, from the switch being set to the model sitting 100% on the GPU and the MCP server being registered. The first call after five idle minutes pays for Ollama unloading the model: 33.8 seconds to read 20.6 GB back from the SSD, and the speed line says so.

A warm call: apu ping answers in 1.5 s, and apu stats shows 12.4 GB free and a median of 11.2 tok/s over the last five requests.

Seven minutes later the model had been unloaded after Ollama's five idle minutes: the same ping took 36.4 s, 33.8 of them loading, and free RAM was 10.9 GB.

Anyone who runs it on another machine gets a JSON file with that machine's specs from apu bench, in ~/.apu/bench/. A pull request that adds it to bench/results/ adds a row to the repository's table, which so far holds this laptop alone.

What it is for

After a day with it, the place it earned is the one the MCP tool was built for: Claude Code hands it bulk text work (summarising, classifying, extracting, reformatting many files) and checks what comes back. It does that well, offline and at no cost per request, and that is the use it stays installed for.