"The GPU does not own the pool. It is allowed a share, and the share is a number you can read."
One Pool, One Referee
Because the GPU has no memory of its own, every byte it uses is a byte the rest of the machine cannot. macOS therefore publishes, per device, a recommended maximum working set — in Apple's words, "an approximation of how much memory, in bytes, this GPU device can allocate without affecting its runtime performance". The fraction of physical memory that recommendation represents is not documented as a formula, and the figure most often quoted — "about 75%" — turns out to be one point on a curve. The code block reads the number on each fleet Mac.
| Alias | Physical | Recommended working set | Fraction | MLX default memory limit | iogpu.wired_limit_mb | Evidence |
|---|---|---|---|---|---|---|
| air | 24 GiB | 17.8 GiB | 74.0% | 22.8 GiB (95%) | 0 | measured 2026-09-15 |
| pro2023 | 128 GiB | 107.5 GiB | 84.0% | — | 0 | measured |
| music | 192 GiB | 161.3 GiB | 84.0% | — | 0 | measured |
| office | 512 GiB | 464.0 GiB | 90.6% | 486.4 GiB (95%) | 0 | measured |
The shape is clearer than any rule of thumb: the operating system holds back a reserve that is large relative to a small pool and small relative to a large one — 6.2 GiB on the Air, 20.5 on the 128 GB MacBook Pro, 30.7 on the two 192 GB Studios, 48 on office. Whether that is a fixed formula or a table inside the kernel is not something user space can tell; what user space can tell is the number, and the number is the one to plan against. A neighbouring quest in this series quotes a "practical ceiling closer to 380 GB" for a 512 GB M3 Ultra; on macOS 26.6.2 the device itself reports 464 GiB, and this quest reports what it read. Fit decisions (previous lesson) and decode predictions use this column, not the sticker.
Two Knobs, Neither a Fence
iogpu.wired_limit_mb is a kernel sysctl that caps how much of the pool the GPU may wire — pin so it cannot be paged. It is 0 on every fleet Mac, meaning the kernel chooses; setting it (with root) lets a GPU process wire more, and the only place it is documented is the mlx-lm README, which advises a value "larger than the size of the model in megabytes but smaller than the memory size of the machine". MLX's own set_memory_limit is the process-side knob, and its default is 95% of physical memory on both machines it was read on — above the operating system's recommendation. Neither knob fences anyone else: raising the wired limit takes memory from the rest of the machine, and a process that ignores the recommendation takes it from the display. The GPU track's word for this was discipline; this lesson's is arithmetic — the share is recommended, not enforced, and the runtime you choose decides whether the recommendation is honoured.
What This Buys a Fleet
The household's inference hub runs an embedding model, two rerankers and a chat model side by side on one 512 GB pool with a memory guard set below the recommendation, and has done so without incident. The same numbers explain why the Air is a witness rather than a host: with 17.8 GiB for the GPU, a 16 GB model leaves nothing for its own context, and the operating system pushed 1.7 GB of other memory to swap to make even the short run work.