MPS Backend Out of Memory on Your Mac? Decode the Numbers, Then Fix It (2026)
TL;DR: MPS backend out of memory means PyTorch hit macOS’s GPU memory cap — roughly two-thirds of your unified memory on smaller Macs, not the full amount printed on the box. Shrink the workload first (smaller checkpoint, lower resolution, CPU VAE). The nuclear PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 disables the limit and can freeze your whole machine — use the Metal wired-limit sysctl instead.
What you’ll be able to do:
- Read the three numbers in the error (
MPS allocated,other allocations,max allowed) and know immediately whether you’re 200 MB short or 8 GB short - Raise your Mac’s real GPU memory ceiling with one
sysctlcommand — a change Ollama, LM Studio, and llama.cpp all pick up too - Decide when the honest fix is a smaller model, and when it’s renting a big NVIDIA card for an afternoon
Honest take: 90% of these errors are a model that never fit in the first place — a 16.5 GB checkpoint on a 16 GB Mac loses to arithmetic, not to a bug. Fix the workload before you touch kernel tunables.
Your Mac has 16 GB, 24 GB, maybe 64 GB of unified memory, and ComfyUI still dies mid-generation with this:
RuntimeError: MPS backend out of memory (MPS allocated: 16.91 GB,
other allocations: 2.77 MB, max allowed: 18.13 GB). Tried to allocate
1.28 GB on private pool. Use PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 to
disable upper limit for memory allocations (may cause system failure).
That exact trace comes from a ComfyUI bug report filed on a Mac Mini M4 with 16 GB of unified memory, running Stable Diffusion 3.5 Large at 1024×1024. Notice the strangeness: the machine has 16 GB of RAM, yet PyTorch claims the “max allowed” is 18.13 GB. To fix this error reliably, you need to understand where that number comes from — because the fix the error message itself suggests is the most dangerous one on the list.
What the three numbers actually mean
Apple Silicon has no separate VRAM. The GPU and CPU share one pool of unified memory, and macOS decides how much of that pool the GPU is allowed to wire down. Metal exposes this ceiling as recommendedMaxWorkingSetSize, and every serious inference tool on the Mac — PyTorch’s MPS backend, llama.cpp’s Metal backend, Ollama since February 2024 — treats it as the effective VRAM limit.
The default ceiling is not your RAM size. On smaller-memory Macs it’s roughly two-thirds of unified memory; on higher-memory machines it’s about three-quarters. Apple doesn’t document the exact formula, but the community-measured values are consistent:
| Unified memory | Default GPU ceiling (Metal) | PyTorch “max allowed” (1.7×) |
|---|---|---|
| 16 GB | ~10.7 GB | ~18.1 GB |
| 24 GB | ~16 GB | ~27.2 GB |
| 32 GB | ~21.3 GB | ~36.3 GB |
| 64 GB | ~48 GB | ~81.6 GB |
| 128 GB | ~96 GB | ~163 GB |
The second column explains the mystery 18.13 GB. PyTorch’s MPS allocator multiplies Metal’s ceiling by a high watermark ratio that defaults to 1.7 — it deliberately allows allocations up to 1.7× the recommended working set before throwing. On the 16 GB Mac Mini: 10.67 GB × 1.7 = 18.13 GB. The error fires when the next allocation would cross that line.
So the three numbers read like this:
- MPS allocated — what PyTorch tensors currently hold (16.91 GB, already past physical RAM, which means macOS was swapping)
- other allocations — non-PyTorch Metal usage in the same process (2.77 MB, negligible here)
- max allowed — Metal’s ceiling × 1.7 (18.13 GB)
And “Tried to allocate 1.28 GB” tells you the gap. If the requested chunk is small and you’re at the line, you have a fragmentation or almost-fits problem that tuning can solve. If you’re 8 GB past a ceiling you can’t raise, no environment variable will save you.
There’s a second watermark, too: PYTORCH_MPS_LOW_WATERMARK_RATIO (default 1.4 on unified-memory machines) is a soft limit where the allocator starts garbage-collecting cached blocks and committing command buffers more aggressively before it ever hits the hard stop.
Step 1: Check whether the model ever fit
Before touching any knob, do the arithmetic the error already did for you. The workflow in the bug report above loads sd3.5_large.safetensors — a 16.5 GB fp16 checkpoint — plus text encoders and a VAE, onto a machine whose GPU ceiling is 10.7 GB. That was never going to work without heavy offloading and swap. The same class of report shows up with SD3.5 on other Apple Silicon machines and with KSampler at high resolutions.
In order of effectiveness:
Use a quantized checkpoint. GGUF and fp8 conversions of SD3.5, Flux, and most 2026 image models cut weights by half to three-quarters. The Q4_0 GGUF of SD3.5 Large is 4.77 GB instead of 16.5 GB — it fits a 16 GB Mac’s ceiling with room for activations. Same logic as LLM quantization; if you’re new to it, the trade-offs mirror our Q4 vs Q5 vs Q6 vs Q8 quality-loss guide.
Drop the resolution, then the batch size. Attention memory scales roughly with the square of latent size. 1024×1024 → 768×768 cuts the sampling peak by nearly half. Batch size 1, always, on ≤16 GB machines.
Move the VAE decode off the GPU. The final decode is a common OOM point because it spikes right when the sampler’s memory hasn’t been released. Launch ComfyUI with --cpu-vae — decode takes seconds longer on an M-series CPU and removes the spike entirely. (On NVIDIA this same spike produces black images instead of a clean error; that variant has its own fix guide.)
Add --disable-smart-memory. ComfyUI otherwise keeps previous models resident to speed up re-runs. On unified memory, that cache competes with your next generation. This flag forces aggressive offloading between runs.
Restart the ComfyUI server after flag changes — refreshing the browser tab changes nothing, a mistake we see in half the GitHub threads on this error.
Step 2: The watermark ratio — what 0.0 really does
The error message suggests PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0, and its own parenthetical — “may cause system failure” — is not boilerplate. Setting the ratio to 0.0 removes the allocation limit entirely. PyTorch will then happily wire memory past your physical RAM, macOS starts compressing and swapping to SSD, the UI beachballs, and on 8–16 GB machines the practical outcome is a frozen desktop and a hard reboot. The limit exists to convert a system-wide freeze into a Python exception. Removing it doesn’t create memory; it removes the airbag.
There’s a narrow case where it’s the right tool: you’re just barely over the line — the error shows a small requested allocation against a nearly-full pool — and you have real headroom between “max allowed” and physical RAM plus swap tolerance. Even then, a finite raise beats 0.0. On a terminal launch:
export PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 # last resort
# or a bounded bump instead — allows ~2.0× instead of 1.7×:
export PYTORCH_MPS_HIGH_WATERMARK_RATIO=2.0
python main.py --cpu-vae
For the ComfyUI desktop app on macOS there’s no terminal to export from. The method that works, per the ComfyUI discussion on the Mac app: right-click ComfyUI.app → Show Package Contents → Contents/Resources/ComfyUI/main.py, and add inside the if __name__ == "__main__": block:
os.environ['PYTORCH_MPS_HIGH_WATERMARK_RATIO'] = '0.0'
Expect to re-apply it after app updates overwrite main.py.
If you find yourself reaching for this on every workflow, you’re treating the symptom. The ceiling itself is adjustable — properly — at the OS level.
Step 3: Raise the real ceiling with one sysctl
macOS exposes the GPU wired-memory limit as a kernel tunable. On macOS Sonoma 14 and everything after it (through Tahoe 26 as of this writing):
# example: 24 GB usable GPU memory on a 32 GB Mac
sudo sysctl iogpu.wired_limit_mb=24576
On Ventura and Monterey the knob is older and takes bytes: sudo sysctl debug.iogpu.wired_limit=25769803776.
The change applies instantly, no reboot. Verify it took effect by loading any GGUF model with llama.cpp or Ollama and reading the init log:
ggml_metal_init: recommendedMaxWorkingSetSize = 24576.00 MB
If that line still shows the old two-thirds value, the sysctl didn’t apply. And because Ollama reads the same Metal property, this one command also raises the ceiling for Ollama, LM Studio, llama.cpp, and MLX — it’s the single highest-leverage memory setting on an Apple Silicon inference box. (Ollama ignoring the old tunable was a known bug fixed back in February 2024; anything you’re running in 2026 respects it.)
Two rules keep it safe, per the community guidance that has held up across macOS releases:
- Leave 8–16 GB for macOS. Sensible overrides: 32 GB Mac → 24,576 MB; 64 GB → 57,344 MB; 128 GB → 122,880 MB. On a 16 GB Mac there’s almost nothing to reclaim — 12,288 MB is the aggressive end, and in our judgment you’re better off fixing the workload than squeezing a machine with no slack.
- Watch Memory Pressure in Activity Monitor. Yellow or red after the change, or visible swapping: lower the number. This is unsupported territory — Apple can change the tunable’s behavior in any update.
The setting resets on reboot. That’s arguably a feature — a bad value can’t brick your boot — but if you want persistence, an /etc/sysctl.conf entry or a LaunchDaemon that re-applies it at login both work.
Why does the raised ceiling fix the PyTorch error? Because “max allowed” is derived from Metal’s ceiling. Raise the ceiling from 21.3 GB to 24.5 GB on a 32 GB Mac and PyTorch’s hard limit moves from ~36 GB to ~42 GB — but more importantly, the allocator stops fighting the low-watermark GC at realistic working sizes, which is where the fragmentation-style failures (“tried to allocate 1.28 GB” with gigabytes theoretically free) come from.
When the Mac is simply the wrong tool
Some jobs won’t fit any consumer Mac at any sysctl value: video models, fp16 20B+ image models, big LoRA training runs. Two honest escape hatches:
- Rent the peak. A cloud RTX 4090 or A100 on RunPod costs a few dollars for an afternoon of heavy generation, and you keep using the Mac for everything that fits. Our rent-vs-buy math covers the break-even.
- Add a dedicated box. A used RTX 3090 still offers 24 GB of dedicated VRAM at 936 GB/s — no two-thirds haircut, no shared pool. The full comparison of that path vs staying on Apple Silicon is in our MacBook vs discrete GPU buying guide.
If you’re weighing a Mac purchase for local AI right now, the memory ceiling in the table above is the spec that matters — it’s why we keep saying the Mac Mini M4 Pro’s real usable GPU memory is smaller than the sticker, a point covered in depth in our M4 Pro review and the 100B-models-on-Mac-Studio guide.
FAQ
Why does “max allowed” exceed my physical RAM? PyTorch multiplies Metal’s recommended working-set size by a high watermark ratio defaulting to 1.7. On a 16 GB Mac: 10.67 GB × 1.7 = 18.13 GB. Allocations between your RAM size and that line are backed by compression and SSD swap — which is why performance collapses before the error ever fires.
Is PYTORCH_MPS_HIGH_WATERMARK_RATIO=0.0 safe?
It removes the only guardrail between a failed workflow and a frozen Mac. Use a bounded value like 2.0 if you must, prefer the iogpu.wired_limit_mb sysctl, and prefer a smaller checkpoint over both.
Does the sysctl trick help Ollama and LM Studio too?
Yes. Both derive available GPU memory from Metal’s recommendedMaxWorkingSetSize, which the sysctl changes directly. One command raises the ceiling for every Metal-based tool at once.
Will this error show up in Ollama or llama.cpp?
Not with this wording — it’s PyTorch-specific. llama.cpp’s equivalent is a failed to allocate buffer error or a warning that allocated size exceeds the recommended max working set; the ceiling and the fix are the same.
Does closing Chrome actually help? On unified memory, yes, unlike on a discrete-GPU PC. Every app competes for the same pool the GPU wires from. Freeing 4 GB of browser tabs is 4 GB of headroom below the watermark. For the NVIDIA version of this whole problem, see the CUDA out-of-memory fix guide.
Recommended Gear
- RTX 3090 — used 24 GB dedicated-VRAM escape hatch when unified memory ceilings bite
- Mac Mini M4 Pro — capable small-model box, once you know its real GPU ceiling
For pairing a local backend on your Mac with coding tools, our sister site covers the editor side at aicoderscope.com, and aifoss.dev covers the self-hosted stack.
Sources
- MPS backend out of memory, Mac Mini M4 16GB, SD3.5 Large — ComfyUI issue #7171
- MPS backend out of memory with SD3.5 — ComfyUI issue #7372
- KSampler MPS backend out of memory — Comfy-Org issue #5810
- Set PYTORCH_MPS_HIGH_WATERMARK_RATIO on Mac App — ComfyUI discussion #7098
- MPS environment variables (watermark defaults 1.7 / 1.4) — PyTorch documentation
- Override macOS Metal VRAM cap on Apple Silicon — ivanopcode dev note
- Reliably determine available VRAM on macOS — Ollama PR #2354
- Ollama ignores iogpu.wired_limit_mb — Ollama issue #1826
- Allocated size greater than recommended max working set — llama.cpp issue #5206
- stable-diffusion-3.5-large model files (16.5 GB fp16) — Stability AI on Hugging Face
- stable-diffusion-3.5-large GGUF quantizations (Q4_0 4.77 GB) — city96 on Hugging Face
- GeForce RTX 3090 specs (936 GB/s) — TechPowerUp GPU Database
Last updated August 10, 2026. macOS tunables and PyTorch defaults change between releases; verify against your own ggml_metal_init log line before relying on any number here.
Was this article helpful?
Thanks for the feedback — it helps improve future articles.
Need hands-on help?
I offer 1-on-1 technical consulting for local AI setup, GPU selection, and AI coding tool configuration — same topics covered on this site.
Book a session — $49 / hour →