How Much Unified Memory Your Mac Gives the GPU: Raising the Wired Limit for Large Local Models (2026)
You bought a Mac with 128GB of unified memory to run a big model locally, and then the model that should fit refuses to stay resident and your tokens per second collapse. The reason is that macOS does not hand the whole pool to the GPU. There is a wired limit, the amount of memory the graphics side is allowed to pin, and by default it sits well below the installed capacity so the CPU, the window server, and the rest of the system keep breathing room. When the weights plus the KV cache push past that ceiling, the runtime spills to slower paths and the decode rate falls off a cliff, which people misread as a bandwidth or quantization problem when it is really an allocation problem. This post measures the default headroom on M4 and M5 machines, shows exactly where common model sizes cross the line, and gives the one sysctl knob that raises the ceiling safely, along with how far you can push it before you starve the OS. If you are speccing or tuning a machine to hold a large model resident, this is the number that actually decides whether it fits.
How Much Unified Memory Your Mac Gives the GPU: Raising the Wired Limit for Large Local Models (2026)
If you bought a Mac with a lot of unified memory specifically to run big models locally, there is a number that decides whether the model fits, and it is not the number on the box. macOS does not let the GPU pin all of installed memory. It enforces a wired limit, a ceiling on how much the graphics side can hold resident, and by default that ceiling sits below capacity so the operating system keeps working memory for itself. When your weights plus the KV cache climb past the ceiling, the runtime spills and your decode speed falls off a cliff. Here is what the default gives you, where common models cross the line, and how to raise it safely.
What the Default Actually Reserves
On Apple Silicon the CPU and GPU share one physical pool of memory, but sharing does not mean the GPU may take all of it. macOS caps the amount of memory that can be wired for GPU use, and the default cap is a fraction of installed capacity. The rule of thumb the system has used is roughly this: on machines with more memory, the GPU may pin most of it, but never all, because the window server, the kernel, your editor, and the runtime process itself all need resident pages that are not GPU allocations. The table below is the practical headroom we measured across current tiers, expressed as how much a model plus its runtime can safely hold before the OS starts to fight back.
| Installed unified memory | Approx default GPU wired ceiling | Practical model + KV budget | Comfortable model size at 4-bit |
|---|---|---|---|
| 36 GB | ~27 GB | ~24 GB | up to ~30B |
| 48 GB | ~36 GB | ~33 GB | up to ~34B |
| 64 GB | ~48 GB | ~45 GB | up to ~70B tight |
| 96 GB | ~72 GB | ~68 GB | 70B comfortable |
| 128 GB | ~96 GB | ~90 GB | 70B with long context, 100B+ dense tight |
Read the last two columns together. The installed number is not the budget. The budget is what is left after macOS holds back its reserve, and then after your own runtime process, the model file mapping, and the KV cache take their share. A 128GB machine does not give a 128GB model home; it gives you roughly 90GB of comfortable resident room once everything else is accounted for. That gap is where people get surprised.
Why Spilling Wrecks Decode Speed
The reason this matters so much is that crossing the ceiling does not fail loudly. It degrades. When the GPU cannot wire all the pages it wants, the system starts moving pages in and out, and on a machine with no discrete VRAM that means the model is effectively being fed through slower memory paths instead of staying pinned and hot. Decode is already the memory bound phase of inference, where every generated token requires reading the active weights out of memory, so anything that slows the path to those weights hits tokens per second directly. We covered why decode speed tracks memory bandwidth almost linearly, and spilling is the ugly version of the same physics: you have not lowered the rated bandwidth, but you have inserted a much slower step into the read path for a portion of the weights, and the average collapses.
The signature is unmistakable once you know it. A model that decodes at a healthy rate for the first few hundred tokens starts to sag, the fans do not necessarily spin up because this is not a thermal problem, and memory pressure in Activity Monitor turns yellow or red. If you have ever watched a 70B model run beautifully and then stutter the moment you loaded a long document into context, you watched the KV cache push the total past the wired ceiling. The weights fit; the weights plus a large KV cache did not.
Where Common Models Cross the Line
The budget has two moving parts: the weights, which are fixed once you pick a model and quantization, and the KV cache, which grows with context length and batch size. The weights are easy to estimate, roughly the parameter count times bits per weight divided by eight. The KV cache is the part people forget, and it is the part that turns a comfortable fit into a spill halfway through a session.
| Model and quant | Weight footprint | KV cache at 32K ctx | KV cache at 128K ctx | Total at 128K |
|---|---|---|---|---|
| 8B 4-bit | ~4 GB | ~1 GB | ~4 GB | ~8 GB |
| 32B 4-bit | ~18 GB | ~3 GB | ~12 GB | ~30 GB |
| 70B 4-bit | ~40 GB | ~5 GB | ~20 GB | ~60 GB |
| 70B 8-bit | ~72 GB | ~5 GB | ~20 GB | ~92 GB |
Put that last row against the 128GB machine's ~90GB comfortable budget and you can see the trap. A 70B model at 8-bit weights fits fine on its own, but push the context toward 128K and the KV cache alone adds another twenty-odd gigabytes, and now you are over the ceiling on a machine that looked like it had room to spare. This is why KV cache growth with context length is not a footnote; it is often the exact thing that decides whether your configuration stays resident. Mixture-of-experts models change the arithmetic again, because their total parameter footprint sits in memory even though only a fraction is active per token, so a large MoE can eat the whole budget with weights before the KV cache even enters the picture.
Raising the Ceiling
macOS exposes the wired limit as a tunable, and raising it is the single most effective fix when your model would fit but the default reserve is squeezing it. The knob is iogpu.wired_limit_mb, set through sysctl, expressed in megabytes.
# Check the current setting (0 means the system default is in effect)
sysctl iogpu.wired_limit_mb
# Raise the GPU wired ceiling to 112 GB on a 128 GB machine
sudo sysctl iogpu.wired_limit_mb=114688
# Revert to the system-managed default
sudo sysctl iogpu.wired_limit_mb=0
The value is a hard cap on what the GPU may wire, so setting it higher gives the model more room to stay resident, but it does so by shrinking the guaranteed reserve for everything else. The setting also does not persist across a reboot on its own; it is a runtime sysctl, so if you want it to survive a restart you script it to run at login rather than trusting it to stick.
How Far You Can Safely Push It
The temptation is to set the ceiling to installed capacity and be done, but that starves the OS and the failure mode is worse than a spill: the whole machine hitches, the window server stutters, and in the extreme the system can become unstable under memory pressure. Leave a real reserve. The guidance below is the reserve we hold back on machines that run large models as a daily workload.
| Installed memory | Reserve to leave for the OS | Safe wired ceiling to set |
|---|---|---|
| 64 GB | ~8 GB | ~56 GB |
| 96 GB | ~10 GB | ~86 GB |
| 128 GB | ~14 GB | ~114 GB |
| 192 GB | ~18 GB | ~174 GB |
| 256 GB | ~24 GB | ~232 GB |
The reserve grows a little in absolute terms with capacity because the bigger machines tend to run bigger everything alongside the model: more browser tabs, a running dev server, a database in the background. Set the ceiling, then watch memory pressure under your real workload for a session. If pressure stays green with the model, the KV cache at your working context, and your normal apps all loaded, the ceiling is right. If it goes yellow, back the ceiling down until it does not. The goal is the largest resident model budget that still leaves the system comfortable, not the theoretical maximum.
Reading Your Own Numbers
If a model that should fit is spilling, walk the budget in order. Estimate the weight footprint from parameters and quantization. Add the KV cache for your actual context length, not the model's maximum. Compare the total against the practical budget for your machine, which is installed memory minus the OS reserve, not installed memory. If the total exceeds the budget, you have three levers: drop to a smaller quantization to shrink the weights, cap the context length to shrink the KV cache, or raise the wired limit to enlarge the budget. Raising the limit is the right move only when the model genuinely fits within a safe ceiling and the default reserve was the only thing in the way. If the model is simply too big for the machine even at a safe ceiling, no sysctl saves you, and the honest answer is a smaller model, a heavier quant, or a bigger box.
When This Applies to Your Stack
If you are putting local inference into a real product, treat the wired limit as a first-class part of the capacity plan, not an afterthought you discover in production. Size the machine so the model plus the KV cache at your worst-case context sits comfortably under a safe wired ceiling with the OS reserve intact, and set the ceiling deliberately rather than trusting the default to be generous. The mistake we see most often is a team buying a high-memory Mac, assuming the whole pool is model budget, and then blaming the runtime or the quantization when decode sags under long context. The budget was always smaller than the sticker, and the KV cache was always going to grow. Plan for the resident total, tune the ceiling to your real workload, and leave the OS its reserve.
If your team is building a local or hybrid inference tier and wants the hardware sized to the resident footprint of your actual model and context budget rather than a spec-sheet capacity number, Contra Collective builds AI infrastructure that models the memory ceiling against your real request pattern, so the machine you deploy holds the model you intended to run.
FAQ
Why does my Mac not use all its unified memory for the model? Because macOS caps how much memory the GPU may wire, and the default cap sits below installed capacity to guarantee the operating system, window server, and your other processes have resident memory. The model gets a large fraction of the pool, but never all of it, so a 128GB machine offers roughly 90GB of comfortable model-plus-KV budget by default rather than the full 128GB.
What is iogpu.wired_limit_mb? It is the macOS sysctl that sets the ceiling, in megabytes, on how much memory the GPU is allowed to wire. Raising it lets a large model stay resident that the default reserve was squeezing out, but it shrinks the guaranteed headroom for everything else, so you set it high enough for the model and no higher than a safe reserve allows.
Why does my model slow down only on long prompts? Because the KV cache grows with context length, and a long prompt can push the weights-plus-cache total past the wired ceiling even when the weights alone fit comfortably. The weights were resident; the weights plus a large KV cache were not, so the system started spilling and decode speed dropped.
How much memory should I leave for macOS? Leave roughly 8GB on a 64GB machine and scale up to around 14GB on 128GB and more on larger configurations. Set the wired ceiling to installed memory minus that reserve, then watch memory pressure under your real workload and back the ceiling down if pressure turns yellow.
Does raising the wired limit make inference faster? Only indirectly. It does not increase memory bandwidth or compute, so a model that already fits sees no speedup. What it prevents is the slowdown from spilling: by keeping a large model resident that would otherwise have been squeezed past the default ceiling, it lets decode run at the machine's real rate instead of the degraded spilling rate.
More from the lab.
Postman's MCP Plugin Installed Itself Into Claude Code and Codex: What the Audit Trail Actually Shows
A developer running Postman Desktop 12.33.4 on macOS found their Claude Code settings and Codex config both quietly enabled with Postman's MCP plugin, logged under a source string that does not appear anywhere in Postman's public plugin repository. The GitHub issue, filed October 25, 2026, has sat open and unanswered. No data breach is proven here, the MCP server failed authentication in the reported case, but the consent gap is real and it is a pattern worth auditing for in your own agentic coding stack regardless of whether this specific vendor is the one that did it to you.
Cisco Gave One Engineer Unlimited AI Tokens to Rewrite 98 Percent of Its Legacy Code
Cisco president and chief product officer Jeetu Patel gave engineer Padmanabhan Krishnamurthy, 27, unlimited AI tokens and a self set four week proof period toward a goal of rewriting 98 percent of Cisco's legacy code within 24 months, with a two person team. Fortune reported it on October 30, 2026. No results have been reported yet, the 98 percent figure is a target. The structure of the bet, not the number, is what enterprise engineering leaders should actually study.
ChatGPT Atlas vs Perplexity Comet: Which AI Browser Actually Works for Enterprise Workflows
Two AI native browsers now compete for the same enterprise seat: OpenAI's ChatGPT Atlas, which launched on Mac in October 2025 with an agent mode gated to paid plans, and Perplexity's Comet, which added a dedicated Enterprise Pro tier with SOC 2 Type II certification, admin permissioning, and MDM rollout to thousands of devices in March 2026. Both sit on Chromium and both will click through a web page on your behalf. What actually differs is who can turn the agent loose, what IT can see once they do, and whether a security team would sign off on either one today.