How to install and tune oMLX on M5 Max 128 GB
Table of contents
- Quick answers
- Install
- Server settings for 128 GB
- Model stack for multi-LLM
- Point Claude Code at the local endpoint
- SSH from another Mac
- Benchmark on real hardware
- End-to-end verification
- What has changed since 0.3.8
- Lightning MTP speculative decoding
- Custom kernels, with a note for M5
- oQ and oQe quantisation
- The neural engine and cold starts
- New endpoints
- Sub-key authentication
- The setting names
- Other pieces that did not exist
- Sources and further reading
- Frequently asked questions
- Do I need to set an API key to use oMLX locally only?
- Can I use Claude Code from a MacBook against oMLX running on a Mac Studio?
- Are the benchmarks in this post still valid if I install 0.6.4?
- Sources
Recipe for oMLX on a Mac M5 Max with 128 GB: install, TurboQuant at 3.5-bit, the Qwen 3.6 35B-A3B model stack, Claude Code wiring and our own benchmarks. Revised for oMLX 0.6.4, with what changed since 0.3.8.
oMLX is an LLM inference server built on MLX, the framework Apple shipped in December 2023 for Apple Silicon. It adds continuous batching, two-tier KV cache (RAM + SSD), and an OpenAI- and Anthropic-compatible API.
On a Mac M5 Max with 128 GB of unified memory you can hold three or four large models at once with TurboQuant 3.5-bit on KV cache. That is enough to feed chat, agent and IDE in parallel. This guide collects the configuration tested in May 2026 to get the most out of that combination.
Quick answers
Which oMLX version do I use and how do I install it? Version 0.6.4 (released 29 August 2026, Apache 2.0). The direct route: download the .dmg from GitHub Releases[1], open it and drag to Applications. Or install via brew tap jundot/omlx https://github.com/jundot/omlx and brew install jundot/omlx/omlx.
The first load of the panel at http://localhost:8000/admin prompts for the API key. The full Homebrew route, including the service that starts on its own, is in installing, updating and uninstalling oMLX with Homebrew.
What TurboQuant setting makes sense on 128 GB? 3.5-bit. vLLM’s independent analysis published 11 May 2026[2] shows 3.5-bit matches full-precision quality with about 4x less KV-cache memory. On M5 Max that turns 128k context from "blows past available RAM" into "fits alongside other loaded models."
Which models can I load concurrently on 128 GB?
Primary: unsloth/Qwen3.6-35B-A3B-MLX-8bit (37.7 GB, MoE with 3B active). Fast helper: Qwen3-14B-Instruct-mlx-4bit (8 GB). Vision: Qwen2.5-VL-32B-mlx-4bit (18 GB).
Embeddings: BGE-M3-mlx (1.2 GB). Reranker: ModernBERT-base-mlx (150 MB). Comfortable sum: ~65 GB with headroom.
How do I point Claude Code at the local endpoint? Since 0.5.0 the short way is omlx launch claude, which exports the variables for you. By hand: export ANTHROPIC_BASE_URL=http://127.0.0.1:8000, ANTHROPIC_AUTH_TOKEN=<your_api_key> and the three ANTHROPIC_DEFAULT_*_MODEL variables (Opus/Sonnet/Haiku).
Launch with claude --bare to drop the system prompt to ~1,795 tokens. The dashboard’s Claude Code with oMLX section assembles the full command for you.
Does this replace Claude Opus 4.7? Not one for one. Claude Code is tuned for Claude’s tool-use format; a non-Claude model behind the endpoint loses reliability in agentic loops. Use this for offline work, sensitive data that should not leave the Mac, or as a fallback when api.anthropic.com is rate-limiting you.
Install
The easiest path: download the .dmg from GitHub Releases[1], open it and drag the app to Applications. The server starts in the background with a menu-bar icon.
Or install via Homebrew:
brew tap jundot/omlx https://github.com/jundot/omlx
brew install jundot/omlx/omlx
omlx start
omlx serve --model-dir ~/models
The first hit to http://localhost:8000/admin prompts for the API key. By default oMLX ships with no API key set (empty field), which is fine for local testing. If the instance only listens on 127.0.0.1 this is safe; the moment you expose it to the LAN or plan to share the endpoint, go to Settings → Auth & Info and set a long random string. The section accepts multiple keys at once.

Server settings for 128 GB
Settings → Global Settings holds the full server configuration. The decisions that matter on a 128 GB machine:
-
Server → Host:
Localhost only (127.0.0.1). If you open it to the LAN, put real auth in front first. -
Server → Port:
8000by default. -
Resource Management → Memory Limit (Total):
Auto. oMLX subtracts what macOS reserves; on 128 GB you end up around 110-114 GB for inference. -
Resource Management → Memory Limit (Models Only):
Auto. Keeps a percentage for activations, KV cache and auxiliary processes. -
Resource Management → Hot Cache Limit:
10%. Intermediate RAM-tier KV cache. With TurboQuant enabled on the models that support it (see below), 10% is the value people running this setup in practice land on for 128 GB. With TurboQuant off and a single model loaded you can drop to Off, but you stop gaining. -
Resource Management → Cold Cache Limit (SSD Cache):
10%. Around 80 GB of SSD for cold tokens without saturating it. -
Resource Management → Max Concurrent Requests:
16. Comfortable for a single user with an agent, a chat session and an IDE pinging at once. Raise to 32 if you share with a small team. -
Resource Management → Idle Timeout:
None. Keeps models warm; the first token arrives in well under a second instead of seconds later. -
Generation Defaults → Max Context Window:
256000as the global default. The Qwen3.6 family holds up at long context, and with TurboQuant the effective RAM stretches enough to actually use it. Each model can be capped lower in Model Settings. -
Generation Defaults → Max Tokens:
64000. Upper bound per response. Going higher only matters if you plan to generate full books in one shot. -
Generation Defaults → Temperature:
1.0for general use,0.2-0.5for code models. -
Model Settings → Experimental Features → TurboQuant KV Cache: enable at
3.5-biton the large dense models. vLLM’s independent study published 11 May 2026[2] of Google’s TurboQuant shows 3.5-bit matches full-precision quality with roughly 4x less KV-cache memory. On M5 Max that makes 128k context fit on models where FP16 does not.

Model stack for multi-LLM
With 128 GB you have room to load one large primary model, a fast helper, a VLM, embeddings and a reranker concurrently. Download them from Models → Downloader by pasting the Hugging Face repo URL.
The recommendation holding up in May 2026 comes from people actually running Claude Code on oMLX on M5 Max (see Diego R. Baquero’s gist[3] for the source): Unsloth’s Qwen 3.6 35B-A3B family in MoE with ~3B active parameters per token. On 128 GB the 8-bit fits without breaking a sweat:
-
Primary (chat + code + reasoning):
unsloth/Qwen3.6-35B-A3B-MLX-8bit(~37.7 GB). MoE 35B with 3B active. The all-rounder: long chat, code, agents. On 128 GB it fits alongside everything else without squeezing. -
More compressed alternative:
unsloth/Qwen3.6-35B-A3B-UD-MLX-4bit(~21.6 GB) if you want two primary models loaded at once. Loses a notch of quality versus 8-bit but leaves room to experiment. -
Dense reasoning (when MoE falls short):
Mistral-Large-2-123B-Instruct-mlx-4bit(~70 GB) orLlama-3.3-70B-Instruct-mlx-4bit(~40 GB). For deep reasoning in a single pass, where a dense architecture beats a small-activation MoE. -
Fast helper:
Qwen3-14B-Instruct-mlx-4bit(~8 GB). For cheap tasks in agents, parsing and summaries. -
Vision:
Qwen2.5-VL-32B-Instruct-mlx-4bit(~18 GB) covers OCR, image description and multimodal reasoning. -
Embeddings:
BGE-M3-mlx(~1.2 GB), dense + sparse + multi-vector in a single model. -
Reranker:
ModernBERT-base-mlx(~150 MB) to close the loop on a decent RAG pipeline.
Comfortable concurrent load with Qwen3.6 35B-A3B 8-bit as primary + 14B helper + VL-32B + embeddings + reranker: around 65-70 GB. Add Mistral Large 2 123B on top for dense reasoning and you hit ~135 GB nominal. The LRU policy moves idle models to SSD, so the cohabitation works in practice for sessions that do not pin everything at once. Pin the primary model from Model Manager so it never gets evicted.
Point Claude Code at the local endpoint
oMLX exposes an Anthropic-compatible API at http://127.0.0.1:8000. In current versions the routes live under /v1: POST /v1/messages and POST /v1/messages/count_tokens. Claude Code respects ANTHROPIC_BASE_URL, so pointing the CLI at your Mac is a matter of exporting environment variables. First, turn off the attribution header in Claude Code’s global config so the gateway does not bolt extra noise onto the prompt:
Since 0.5.0 there is a shortcut that does all of this for you and did not exist when this recipe was written:
omlx launch claude
It sets ANTHROPIC_BASE_URL against your server, puts the configured key in ANTHROPIC_AUTH_TOKEN (or omlx if there is none), empties ANTHROPIC_API_KEY to force the base URL to be used, raises API_TIMEOUT_MS to 3,000,000 and disables non-essential traffic. It also sets CLAUDE_CODE_MAX_CONTEXT_TOKENS and CLAUDE_CODE_AUTO_COMPACT_WINDOW to what the engine can actually do, which is what the context-scaling option used to do by hand. It enforces a minimum window of 48,000 tokens and will not start if the chosen model falls short. There are equivalent commands for Codex, OpenCode, OpenClaw, Hermes and Pi, described in the dashboard and command line guide.
The manual recipe below still works and is the one to use if you want fine control over each variable.
~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_ATTRIBUTION_HEADER": "0"
}
}
Then the startup command:
export ANTHROPIC_BASE_URL=http://127.0.0.1:8000
export ANTHROPIC_AUTH_TOKEN=<your_api_key>
export ANTHROPIC_DEFAULT_OPUS_MODEL=unsloth/Qwen3.6-35B-A3B-MLX-8bit
export ANTHROPIC_DEFAULT_SONNET_MODEL=unsloth/Qwen3.6-35B-A3B-MLX-8bit
export ANTHROPIC_DEFAULT_HAIKU_MODEL=Qwen3-14B-Instruct-mlx-4bit
export ANTHROPIC_DEFAULT_MODEL=unsloth/Qwen3.6-35B-A3B-MLX-8bit
export API_TIMEOUT_MS=600000
export CLAUDE_CODE_USE_BEDROCK=0
export DISABLE_NONESSENTIAL_TRAFFIC=1
claude --bare
The --bare flag skips hooks, LSP, plugin sync and auto-memory, dropping Claude Code’s system prompt to around 1,795 tokens (versus the thousands it uses with everything loaded). For offline work against a local model that is the sensible default: every token in the system prompt is bandwidth your Mac would otherwise burn. Drop the flag when you point back at api.anthropic.com.
The oMLX dashboard builds this command for you in the Claude Code with oMLX section: pick Opus, Sonnet and Haiku from three dropdowns and copy the ready-to-paste command. Set Context scaling for Claude Code to 64000: Claude Code requests 200k tokens by default, but a local model behaves better with a 64k ask than a 200k ask it cannot honor. The option scales the reported counts so auto-compact triggers at the target size.

A real caveat: Claude Code is tuned to Claude’s tool-use format and response patterns. A non-Claude model behind ANTHROPIC_BASE_URL works for autocomplete and reasoning, but you will see drops in tool-call reliability and in agentic loops. Use this for offline work, sensitive data that should not leave the Mac, or as a fallback when api.anthropic.com is rate-limiting you. It is not a 1:1 substitute for Claude Opus 4.7.
SSH from another Mac
If oMLX runs on a Mac Studio and you want to use Claude Code from your MacBook, SSH port forwarding is the bridge:
ssh -L 8000:localhost:8000 user@mac-studio
Once connected, 127.0.0.1:8000 on your laptop points to the Studio’s oMLX. Save this script as claude-local.sh:
#!/bin/bash
export ANTHROPIC_BASE_URL='http://localhost:8000'
export ANTHROPIC_AUTH_TOKEN=''
export ANTHROPIC_DEFAULT_OPUS_MODEL='Qwen3.6-35B-A3B-MLX-8bit'
export ANTHROPIC_DEFAULT_SONNET_MODEL='Qwen3.6-35B-A3B-MLX-8bit'
export ANTHROPIC_DEFAULT_HAIKU_MODEL='Qwen3-14B-MLX-4bit'
export ANTHROPIC_DEFAULT_MODEL='Qwen3.6-35B-A3B-MLX-8bit'
export API_TIMEOUT_MS=600000
export CLAUDE_CODE_USE_BEDROCK=0
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
claude --bare --dangerously-skip-permissions
Make it executable with chmod +x claude-local.sh and run it from the SSH session. The default API key is the empty field. If you set one in Settings → Auth & Info, replace '' with it.
--bare drops Claude Code’s system prompt to ~1,795 tokens. --dangerously-skip-permissions bypasses interactive permission prompts that don’t make sense in an automated pipeline.
Benchmark on real hardware
Bench → Performance runs tests on your actual hardware. The panel covers prefill at eight prompt sizes (pp1024, pp4096, pp8192, pp16384, pp32768, pp65536, pp131072, pp200000) and continuous batching at 2x, 4x and 8x concurrency. Submit your results to the public oMLX leaderboard[4] from My Submissions to compare against other machines on the same profile.
Reference numbers measured on M5 Max 40-core with 128 GB on oMLX 0.3.8, in May 2026. Not extrapolated (the omlx.ai leaderboard[4] already has M5 Max submissions, and vLLM’s independent TurboQuant study published 11 May 2026[2] confirms the figures for the large dense models):
- Qwen 3.6 35B-A3B 8-bit (MoE, 3B active): 65-80 tok/s on decode at short context. The model that most changes day-to-day use on this machine. Live benchmarks from this setup:
| Test | TTFT | Decode TPS | E2E | Peak Mem |
|---|---|---|---|---|
| pp1024/tg128 | 577 ms | 72.4 tok/s | 2.35s | 38.5 GB |
| pp4096/tg128 | 1,293 ms | 83.1 tok/s | 2.83s | 36.2 GB |
| pp8192/tg128 | 2,995 ms | 82.1 tok/s | 4.55s | 36.5 GB |
| pp32768/tg128 | 13,785 ms | 15.2 tok/s | 22.18s | 40.9 GB |
Continuous batching (pp1024 / tg128):
| Batch | Decode TPS | Speedup |
|---|---|---|
| 1x (baseline) | 72.4 tok/s | 1.00x |
| 2x | 87.1 tok/s | 1.20x |
| 4x | 123.8 tok/s | 1.71x |
| 8x | 237.7 tok/s | 3.28x |
-
Llama 3.3 70B 4-bit: 14-18 tok/s on decode.
-
Mistral Large 2 123B 4-bit with TurboQuant 3.5-bit on KV cache: 8-11 tok/s on decode. The number that matters at 128k context is peak memory, ~74 GB (FP16 KV blows past 128 GB). dasroot.net’s long-context M5 Max experiment[5] documents the same peaks for the 104B dense model.
-
gpt-oss-20b MXFP4-Q4 on M5 Max 40c per the public oMLX benchmark submission[6] lands around 100 tok/s on decode.
The tables above are our own measurement on 0.3.8 and have not been re-run on 0.6.4. Read them as a floor, not a ceiling: the project later measured a 1.57x decode gain on this same model from Lightning MTP, though on an M3 Ultra. It is detailed below.
vLLM measured the TurboQuant KV-cache compression at 4.41x in May 2026. That figure is what separates "I have 128k context but it does not fit" from "I have it and can load two other models alongside it". At 4-bit and 3.5-bit, quality stays close to full precision; at 3-bit you start to feel it in code and long-form reasoning.

End-to-end verification
A curl call to the OpenAI-compatible API to confirm the server is alive and a model responds:
curl http://127.0.0.1:8000/v1/chat/completions
-H "Authorization: Bearer <your_api_key>"
-H "Content-Type: application/json"
-d '{
"model": "Qwen3-Coder-30B-A3B-Instruct-mlx-8bit",
"messages": [{"role":"user","content":"Hello from oMLX"}]
}'
And from Claude Code, once you have exported the variables from the previous section:
claude --print "Are you running locally?"
The reply should come back from local without touching api.anthropic.com. To confirm at the network level, open Activity Monitor → Network, filter by the claude process and check that the outbound connection is against 127.0.0.1:8000.

What has changed since 0.3.8
This guide was written against oMLX 0.3.8 in May 2026. The current version is 0.6.4, released on 29 August 2026, and more than a dozen releases in between touch exactly what is tuned here. What follows is the summary of what changed, with the figures attributed to whoever measured them.
Lightning MTP speculative decoding
This is the change that affects this configuration most. Version 0.5.0, from 10 July 2026[7], added native depth-k speculative decoding for Qwen3.6-27B, Qwen3.6-35B-A3B, DeepSeek-V4-Flash and GLM-5.2.
On an Apple M3 Ultra the project measured Qwen3.6-35B-A3B going from 89.6 to 140.4 tok/s, a 1.57x gain. Qwen3.6-27B went from 35.0 to 55.1 tok/s. Those are the project’s figures on M3 Ultra, not this M5 Max: the tables above remain our own measurement on 0.3.8 and are still due a re-run.
Custom kernels, with a note for M5
The same 0.5.0 added custom compute kernels for DeepSeek V4, Qwen3.5/3.6 and GLM-5.2, with prefill improvements measured on M3 Ultra. They are 45% on DeepSeek-V4-Flash (313.3 to 455.8 tok/s at 64k context), 33% on Qwen3.6-27B and 99% on GLM-5.2 at 32k. What matters for this machine is that dispatch is NAX-aware precisely to avoid regressions on the M5 series, so it is worth confirming the effect rather than assuming it.
oQ and oQe quantisation
oMLX no longer depends only on the weights you download: it brings its own quantisation scheme. Version 0.5.0 added oQe, an activation-importance calibration pass with expert-coverage tracking for MoE models. In the project’s measurements oQ4e improves average accuracy over oQ4 while staying in the same disk-size class. That is 83.88% against 82.83% on Qwen3.6-35B-A3B, and 73.09% against 70.01% on Qwen3.5-9B.
The neural engine and cold starts
The 0.6.3 branch worked on the prefill path over Apple’s neural engine. Two of the project’s figures matter day to day. Bank compilation memory dropped from 35.8 GB to 4.7 GB, and an optional persistent compile cache cuts fresh-process startup by 53% to 66%. Version 0.6.4 continued down that road and improved Qwen3.8-Flash-Next prompt processing by 33.5%, with 24.2% less total request time at 32k, again on M3 Ultra.
New endpoints
The OpenAI- and Anthropic-compatible pair has been joined by /v1/rerank for document reranking, /v1/responses for Codex compatibility and /v1/mcp/tools for Model Context Protocol. With an embedding model and a reranker loaded at once, a whole retrieval pipeline fits on the same server. The full breakdown is in the guide to the API, the key and the port.
Sub-key authentication
Where there used to be a list of equivalent keys, there are now three credentials with different powers. A main key opens the API and the panel; sub-keys only call the API and cannot log into the panel or change settings; panel session tokens are held in a signed cookie. If you are handing access to more than one application, hand out sub-keys.
The setting names
The memory configuration in the earlier section still holds as judgement, but the keys are named differently in ~/.omlx/settings.json. The memory ceiling is now memory_guard_tier, with four levels (safe, balanced, aggressive and custom), and the bespoke value goes in memory_guard_custom_ceiling_gb. By default the ceiling is system RAM minus 8 GB. The two cache tiers are hot_cache_max_size and ssd_cache_max_size, and the concurrency limit is max_concurrent_requests.
Watch one of them: hot_cache_max_size ships as "0", which disables the hot cache in RAM. I go through it in benchmarks and the memory ceiling.
Other pieces that did not exist
Profiles save named bundles of settings over a single model, exposed as model:profile and at no extra memory cost. Aliases rename a model as far as the API is concerned. And there is experimental distributed inference, splitting a model’s layers across more than one Mac over SSH according to each machine’s memory, accounting for whether the link is Thunderbolt or 10GbE. The first two are in the dashboard and command line guide.
Sources and further reading
-
Diego R. Baquero, "Running Claude Code with a local LLM"[3]: the tested configuration recipe this post’s settings are based on (TurboQuant 3.5-bit, 64k context, attribution off, Qwen 3.6 35B-A3B models).
-
A First Comprehensive Study of TurboQuant, vLLM blog, 11 May 2026[2]: independent analysis confirming 3.5-bit matches full-precision quality.
-
omlx.ai/benchmarks[4]: public leaderboard with real submissions from M5 Max and other machines.
-
Maxing Out M5 Max Context Windows: Memory Fragmentation and TurboQuant Benchmarks (dasroot.net, April 2026)[5]: the other detailed experiment on long-context M5 Max with TurboQuant.
-
Repositories: jundot/omlx[8], ml-explore/mlx[9], ml-explore/mlx-lm[10], huggingface.co/mlx-community[11], huggingface.co/unsloth[12].
If you came here wondering what this actually is and how it differs from Apple’s MLX framework, I separate the two in what is oMLX. For a cross-platform alternative outside Apple Silicon, the Ollama local LLM guide covers the model catalogue and OpenAI-compatible API. To wire the local endpoint into an agent, the Anthropic SDK tutorial and the MCP multi-vendor patterns already talk to this same format with no code changes.
Related resources
Frequently asked questions
Do I need to set an API key to use oMLX locally only?
No. oMLX ships with the API key field empty, and as long as the instance only listens on 127.0.0.1 that is safe for local testing. The moment you expose it to the LAN or share the endpoint, go to Settings → Auth & Info and set a long random string. Current versions also offer sub-keys that can only call the API and cannot log into the panel or change settings, meant for handing access to more than one application.
Can I use Claude Code from a MacBook against oMLX running on a Mac Studio?
Yes, through SSH port forwarding: ssh -L 8000:localhost:8000 user@mac-studio makes 127.0.0.1:8000 on the laptop point at the Studio's oMLX. Then export the same variables (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN and the ANTHROPIC_DEFAULT_*_MODEL set) in a script such as claude-local.sh, make it executable with chmod +x and run claude --bare from the SSH session. If you set a key in Settings → Auth & Info, replace the empty string with it.
Are the benchmarks in this post still valid if I install 0.6.4?
Read them as a floor, not a ceiling: the tables were measured on oMLX 0.3.8 in May 2026 and have not been re-run on 0.6.4. In between, version 0.5.0 added Lightning MTP speculative decoding. With it the project measured Qwen3.6-35B-A3B going from 89.6 to 140.4 tok/s (1.57x), though on an M3 Ultra rather than this M5 Max. Check the effect on your own machine from Bench → Performance before taking it for granted.
Sources
- GitHub Releases
- vLLM’s independent analysis published 11 May 2026
- Diego R. Baquero’s gist
- public oMLX leaderboard
- dasroot.net’s long-context M5 Max experiment
- gpt-oss-20b MXFP4-Q4 on M5 Max 40c per the public oMLX benchmark submission
- Version 0.5.0, from 10 July 2026
- jundot/omlx
- ml-explore/mlx
- ml-explore/mlx-lm
- huggingface.co/mlx-community
- huggingface.co/unsloth