Most GPU offload advice for LM Studio was written for a PC with a discrete graphics card, and on that machine the advice is right: the card has its own memory, moving layers into it costs a bus transfer, and picking how many layers fit is a real optimization problem.
None of that is true on a Mac. Apple Silicon has unified memory. The CPU and the GPU address the same physical DRAM. There is no card, no separate pool, and nothing to copy across. So when you drag LM Studio's GPU offload slider on an M-series Mac, you are not deciding where the weights live. They live in the same place either way.
What does GPU offload actually do on Apple Silicon?
It picks how many of the model's transformer layers execute on the Metal backend instead of on the CPU. Because Apple Silicon memory is unified, no data moves when you change it: the weights are already in RAM that both processors can read. Setting it below maximum on a Mac means asking the CPU to do work the GPU would do faster, on exactly the same bytes.
That is why the usual PC tuning instinct backfires here. On a desktop with a 12GB card, holding back a few layers is how you avoid an out-of-memory error. On a 32GB Mac, holding back a few layers just makes generation slower for no memory saving at all.
The practical rule on Apple Silicon is short: offload everything, unless the model does not fit. If it does not fit, the fix is a smaller quantization or a shorter context, not a partial offload.
Why does LM Studio still show me a slider then?
Because it is one app across macOS, Windows and Linux, and on two of those three the slider is load-bearing. LM Studio exposes GPU offload as a per-model default alongside context size and Flash Attention, and the same control is available from its CLI as lms load --gpu. It is not a Mac-specific control that is behaving strangely. It is a cross-platform control that has much less to do on a Mac.
So why does my Mac still refuse to load the model?
Because the limit on Apple Silicon is not VRAM, it is the working-set ceiling macOS reports to Metal. That ceiling is a fraction of installed RAM, not all of it. On our own M2 Max with 32GB, Metal reports a recommended maximum working set of 26,800,603,136 bytes, which is roughly 25GiB of the 32GB installed. The rest is reserved for everything else the machine is doing.
This is the number that actually decides whether a model loads, and it is the one nobody talks about, because on a PC the equivalent figure is printed on the box. Three consequences follow, and they explain most of what looks like a bug:
Your usable budget is smaller than your RAM. A 32GB Mac is not a 32GB inference budget. Size models against roughly three quarters of installed memory and you will be close.
Context length is part of the model's footprint. The KV cache grows with context and it comes out of the same budget as the weights. A model that loads fine at 4K can fail at 32K without a single byte changing in the model file.
Everything else on the Mac is competing. Browser tabs, Xcode, a Docker daemon. The ceiling is fixed but the free space under it is not.
What about raising the limit with iogpu.wired_limit_mb?
You will find advice telling you to raise the wired-memory limit with a sysctl so Metal can claim more of your RAM. It does work, and it is a real knob rather than folklore.
The catch is what it is protecting. That headroom is what macOS uses to stay responsive under pressure, and a wired-memory overflow on Apple Silicon is not a recoverable allocation failure that an app can catch and report. It is a kernel-level fault. Raising the limit to squeeze in a model that nearly fits trades an error message you can read for a hang you cannot. We deliberately do not read or set that sysctl in our own engine for exactly this reason.
If you want the extra headroom for a specific session, set it, run the session, and set it back. Do not leave it raised as a permanent configuration.
How to fix it inside LM Studio
In order, cheapest first. None of these require leaving the app.
The alternative: no slider, because the answer never varies
Everything above is the reason ToolPiper does not have a GPU offload control. On Apple Silicon the correct value is always maximum, so the engine is launched with full Metal offload every time and there is nothing to tune. We embed upstream llama-server directly, build b10068, and pass all layers to Metal on every load.
The number that actually matters is the one we do read. The app queries the live Metal working-set ceiling and your installed memory, and sizes model suggestions against them, so the model list tells you what your Mac can hold before you spend the download. On the MLX side the same reading is a hard admission gate: a load that would not fit is refused before any allocation happens, rather than being attempted and taking the machine down with it.
Models arrive as plain, named GGUF files in ~/Library/Application Support/ToolPiper/models/, so nothing about this locks you in. Same models, same engine lineage, and on inference speed expect parity: our same-bytes benchmark on an M2 Max landed within single digits in both directions with the winner flipping by model.
The honest limits: macOS 26 or newer and Apple Silicon only. LM Studio's floor is macOS 14.0, so if you are on an older system it is the one that runs.
Worth naming, since an offload ceiling is usually the moment people start comparing: neither app charges you to run a model. LM Studio's local tier is free and its cloud tier is metered per token. Ours puts the whole runner in the free tier, memory handling included. The free versus paid split, with dated prices.