Gemma 4 31B MLX vs GGUF on an M4 Pro: 12.6 tokens a second against 11.7

Gemma 4 31B MLX vs the QAT GGUF in LM Studio on a 48 GB M4 Pro: 12.6 against 11.7 tokens a second, a 9 percent faster long read, and no reasoning text.

0:00
Gemma 4 31B MLX vs GGUF on an M4 Pro: 12.6 tokens a second against 11.7

Gemma 4 31B has answered every question on our test machine from the same GGUF file for months, at about 11 tokens a second. On 12 October 2026 we downloaded the Gemma 4 31B MLX build, loaded it in the same copy of LM Studio and ran both through one script. The MLX build wrote 12.6 tokens a second where the GGUF wrote 11.7. Earlier the same day, the same switch had cut a long prompt read on a Qwen model from 75 seconds to 30. On Gemma it cut 286 seconds to 261. This piece covers what moved, what did not, and one difference between the two builds that has nothing to do with the engine.

How we compared the Gemma 4 31B MLX build with the QAT GGUF

The test machine is an M4 Pro with 48 GB of unified memory, on macOS 27.0.1 with LM Studio 0.4.25. The GGUF side was the file we already use: the LM Studio team’s Q4_0 GGUF of Google’s quantisation-aware-trained release, 18.85 GB, on the llama.cpp engine at version 2.47.0. The MLX side was the LM Studio team’s 4-bit MLX build, 18.44 GB, on the MLX engine at version 1.11.0.

Those two are not the same weights at the same precision. The GGUF card names gemma-4-31B-it-qat-q4_0-unquantized as its original model. The MLX card names gemma-4-31B-it, the standard release, quantised to 4 bits afterwards. So this is a comparison of the two files a Mac owner can download today, and it says nothing about which one gives better answers. We did not test answer quality.

Each build was loaded alone with nothing else in memory. One Python script sent every request to LM Studio’s OpenAI-compatible endpoint, streamed the reply and took its timings from the stream. Temperature was 0, and every fresh prompt began with a new random session id so that the prefix cache could not answer it, the trap we described in our prompt processing speed measurement. The tests were the same four we used on Qwen3.6 35B-A3B in our MLX vs llama.cpp run: a short question with a 500-token cap, a long agent-style prompt of about 19,870 tokens with eight tool definitions, five follow-up turns on top of it, and two requests at once.

Is Gemma 4 31B faster on MLX than on llama.cpp?

Slightly, on a single request. The table has every timed figure.

Bar chart of time to first token for Gemma 4 31B on a 19,870-token prompt: llama.cpp took 285.8 and 286.9 seconds, MLX took 260.8 and 262.3 seconds.

Gemma 4 31B, QAT Q4_0 GGUF on llama.cpp 2.47.0 against the 4-bit MLX build on MLX 1.11.0, time to first token on a fresh 19,870-token prompt. Tested 12 October 2026.

Testllama.cpp 2.47.0, QAT Q4_0MLX 1.11.0, 4-bit
Short prompt, tokens written per second12.1, 11.7, 11.712.9, 12.6, 12.5
Long prompt, time to first token285.8 s and 286.9 s260.8 s and 262.3 s
Long prompt, tokens read per second70 and 6976 and 76
Follow-up turn, time to first token8.13 to 8.88 s7.39 to 9.59 s
Two requests at once, tokens per second each5.7 and 5.711.5 and 11.5
Process memory after the run19.9 GB17.4 GB

Writing speed rose by about 7 percent, from a middle value of 11.7 tokens a second to 12.6. The long read fell by about 9 percent, from 286 seconds to 261. Follow-up turns overlapped: llama.cpp started each one in 8.1 to 8.9 seconds and MLX in 7.4 to 9.6.

The llama.cpp figures agree with what this machine has reported before. We measured 65 tokens a second for prompt processing on this GGUF in August and 70 here. A dense 31B model reads every one of its weights for every token it writes, so on both engines the wait is for the same 18 GB to pass through the same memory. A faster engine has little left to remove. That is our reading of why Gemma moved by single digits while a mixture-of-experts model, which computes with only its active parameters, moved by a factor of 2.5 on the same day.

The one large change is the last timed row. When we measured two agents on one LM Studio endpoint in September, the GGUF gave each caller half its speed and the total stayed at about 11 tokens a second. It did the same here: 5.7 tokens a second each, 91.5 seconds for the pair. The MLX build gave each caller 11.5 tokens a second and finished the pair in 38.2 seconds, close to the 34 to 36 seconds one request had taken alone.

Why the Gemma 4 31B MLX build answers sooner than the GGUF

The two builds differed in one way that the speed figures hide. The GGUF wrote reasoning before every answer. The MLX build wrote none.

On the short question, the GGUF spent all 500 tokens of its cap on reasoning text, about 2,000 characters of it, and returned an empty reply in all three runs. The MLX build returned the answer itself in 413 to 428 tokens with no reasoning text. On the long prompt, the GGUF used its whole 120-token cap on reasoning and gave no answer. The MLX build answered in 36 tokens.

The follow-up turns show what that does to an agent loop. Each turn asked for a two-word reply. The GGUF used its 60-token cap on reasoning every time and never printed the reply, and a turn took 13.7 to 14.5 seconds. The MLX build printed the reply in 4 tokens and a turn took 7.4 to 9.6 seconds. At nearly the same tokens per second, the MLX build finished each step in a little over half the time because it wrote fewer tokens.

We did not set any reasoning option on either load, and we did not establish why the two builds behave differently. The chat template travels with each build, so the template is the first place we would look. What we can say is that, with LM Studio’s defaults on both, a reader who switches engines for speed will also get a model that stops thinking out loud. That may be welcome in a tool loop and unwelcome on a hard question. It should be a choice, and here it arrived as a side effect.

Both builds passed the same functional checks. Each returned the right tool with valid arguments in all eleven tool-calling requests, including one at the end of the long prompt. Each returned schema-valid JSON for three structured output requests, although the numbers inside were poor on both: asked for London’s population as an integer, the GGUF wrote 79 and the MLX build wrote 8. Each read the text out of a test image correctly.

Which Gemma 4 31B build to run in LM Studio on a 48 GB Mac

If one agent talks to the model at a time, the engine is not the reason to switch. Seven percent on writing and nine percent on reading is real and too small to feel. The QAT GGUF also has the plainer memory behaviour. We asked for 32,768 tokens of context on both loads. The GGUF loaded at 32,768. The MLX build loaded at 71,936, and LM Studio’s own tracker carries that as issue 2318, opened on 23 August 2026 against the same MLX engine version. On a machine where an unplanned context size has caught us before, that matters more than half a token a second.

If two agents share the endpoint, the MLX build is the better file on these numbers, because it doubled the combined output where the GGUF split it. And if your agent’s steps are short, the missing reasoning will shorten them further, with the caveat that we have not checked what it does to the quality of the work.

Every figure here comes from two or three requests on one machine on one day. The next measurement worth making is the one this run could not: the same questions put to both builds, scored on the answers. Until that exists, the honest position on Gemma 4 31B is that MLX is a different build with a different habit, and only marginally a faster one.

S

Stride El

is an editor at StrideNote.net: writes most of the notes, keeps the site running, and replies to email.