Benchmark · Apple M4 Max 128 GB · October 2026

The best way to run Qwen3.8-Flash-Next on an M4 Max 128 GB

Five local inference servers, the same model and its Swift 1.5 fine-tune, contexts from 8K to 1M tokens. I measured what you wait for in a real agent session, not only tokens per second.

Chip Apple M4 MaxGPU 40 cores · Metal 4Unified memory 128 GBmacOS 26.6.2Measured 2026-10-07 to 2026-10-25

Result: Splash 1.4.0 with the unsloth UD-IQ4_XS GGUF has the shortest agent turn at every context size: 6.8 s at 128K, 7.3 s at 512K, 10.5 s at 1M. It is the only server that reached 1M. Its cost: a change halfway in the history prefills the whole prompt again. If your agent edits, compacts or forks the history often, use mlx-serve 26.10.3 with the ddalcu iQ-MLX 4.7 bpw quant (8.9 s at 128K, 14.5 s at 512K). Conclusion · commands.

Goal

The best stack for Qwen3.8-Flash-Next as a daily driver on one Mac Studio (M4 Max, 128 GB): a 125B mixture-of-experts with 6B active parameters and a native context of 262K tokens.

Weights

Each server runs the pack its author publishes, in its own format, 4.7 to 5.97 bits per weight (table). The results compare server + quant pairs, not servers alone.

Precision

A personal test, not a lab benchmark: one machine, one test prompt, 1 to 3 runs per point. Small differences can be run-to-run variation.

Table of contents

    1 · The seven stacks

    The first five rows run the base model; the last two run the Swift 1.5 fine-tune. Same test prompt, same sampling (temperature 1.0, top_p 0.95, top_k 20, reasoning effort xhigh, max 4,096 output tokens). All use speculative decoding and a prefix cache; they differ in where the cache lives and in how they handle the memory limit. Why these servers and when each ran: section 8.

    ServerWeights (quant)DiskPrefix cache lives inSpeculative decodingLargest context on 128 GB
    mlx-serve 26.10.3
    MLX server by ddalcu
    ddalcu iQ-MLX 4.7 bpw107 GBRAM (16 GB) + disk (100 GB)MTP + n-gram lookup512K (YaRN 2.0 + 4-bit KV cache)
    oMLX 0.7.0
    MLX server by Jundot
    Jundot oQ4e-mtp (5.97 bpw)132 GBpaged, spills over to SSDMTP262K (no YaRN support)
    MTPLX 2.12.2
    MLX server by Youssofal, ships its own quant packs
    MTPLX Optimized-Speed (5.43 bpw)120 GBsession bank in RAM + SSDMTP (depth 3)128K, only with --memory-limit max
    ds4 (antirez, build 0aaea5a)
    antirez's inference engine, Metal backend, GGUF weights
    antirez Q4 GGUF177 GBon disk (100 GB)MTP (1 draft token)512K (YaRN 2.0)
    Splash 1.4.0
    Inco AI's native Metal engine, GGUF weights only
    unsloth UD-IQ4_XS GGUF94 GBRAM (8-bit KV cache) + SSD (32 GiB)DFlash2 draft model1M (YaRN, the KV past ~860K tokens on SSD)
    Splash 1.4.0 / Swift 1.5
    Inco AI's native Metal engine, GGUF weights only
    ukisai Swift 1.5 IQ4_XS GGUF98 GBRAM (8-bit KV cache) + SSD (32 GiB)DFlash2 draft model1M (YaRN, the KV past ~860K tokens on SSD)
    mlx-serve 26.10.3 / Swift 1.5
    my daily driver: the Swift 1.5 fine-tune in MLX
    Dankpaws Swift 1.5 MLX 4.7 bpw99 GBRAM (16 GB) + disk (100 GB)MTP + n-gram lookup512K (YaRN 2.0 + 4-bit KV cache)

    2 · Agent turn time by context size

    Agent turn time = the wait from sending a tool result to the end of a 512-token reply: TTFT (time to first token) + 512 ÷ decode speed. A coding agent pays this at every step. Lower is better. Pick a context size: one panel per metric, then the turn time across all sizes.

    Context size

    Tokens per second is not the whole story. At 128K, MTPLX decodes almost as fast as mlx-serve (70 vs 74 tokens/s), but its turn takes 15.1 s against 8.9 s: its TTFT on the next turn is 7.8 s and its prefill runs at 274 tokens/s against 759. Compare servers on turn time and cache behavior.

    Context size
    Decode speed vs agent turn timebest = bottom right
    Decode speedtokens/s · higher is better

    Splash: 99 tokens/s at 128K with the base model, 108 with Swift 1.5. mlx-serve: 74. ds4 stays at 43–54.

    Prefill speed (cold prompt)tokens/s · higher is better

    MTPLX drops to 274 tokens/s at 128K. The others stay almost flat.

    3 · The cache decides the wait

    In an agent session, every step sends the whole conversation again plus a small new part at the end. A server with a prefix cache keeps the already processed part and prefills only the new tokens. The wait is the tokens that miss the cache, divided by the prefill speed. No server prefilled faster than 832 tokens/s on this machine, so the scenario decides how many tokens miss. At 512K: 1K ≈ 1.5 s · 10K ≈ 15 s · 100K ≈ 2.5 min · 300K ≈ 7.5 min · 512K ≈ 13 min.

    First message whole prompt prefilled from scratch · 512K tokens 13 min Next turn cache hit 4.1 s ~1K new tokens History changes halfway cache hit prefilled again · ~293K tokens 8 min

    mlx-serve at 512K. The bar lengths are schematic; the times are measured.

    CaseTokens prefilled againWait at 512KWhen it happens
    First message512K (100%)13 minA session that already starts with 512K, or an empty cache. In daily use the context grows step by step, so this cost is paid in small parts, never at once.
    History changes halfway~293K (56%)8 minAn edit of an earlier message, a compaction, a new system prompt or tool list, or a fork. The cost is the tokens after the point that changed.
    Next turn~1K4.1 sEvery normal step: the tool result or the new message at the end.

    Splash is the exception. When the history changes halfway it reuses none of the prompt: 13 min at 512K with the base model, against 8 min on mlx-serve. Section 5 explains why.

    Context size
    first message (cold prefill)history changes halfwaynext turn (cache hit)

    A 95% cache hit is not enough at long context

    All seven stacks hit the cache on the next turn. At 512K, ds4 hits 94.5% and prefills about 29K tokens again, so its next reply starts after 50 s. mlx-serve hits 99.8%, prefills about 1K tokens and starts after 4.1 s.

    Context size
    1% ≈ 8 sRule of thumb at 512K: each 1% of cache miss is about 5,243 tokens, or about 8 s of extra wait on this machine.
    TTFT on the next turn (cache hit)s · lower is better

    mlx-serve stays under 4 s up to 512K. ds4 grows from 6.4 s at 128K to 50 s at 512K.

    Cache hit rate on the next turn% · higher is better

    At 512K the gap between 94.5% and 99.8% is about 28,000 tokens.

    Cache hit by scenario

    Share of the prompt the server took from the cache. First message is 0% by design. History changes halfway can reuse at most the part before the change; Splash reuses none. The two scenarios an agent repeats all day are user adds a message and next turn: above 90% is good.

    Context size

    4 · Context limits and memory on 128 GB

    The native context is 262,144 tokens. 512K uses YaRN 2.0, a context extension that oMLX does not support. 1M ran only on Splash. A cell shows the agent turn time, or why that size did not run.

      Peak memory locked by the serverGB · of 128 GB

      No server used swap. mlx-serve locks 100–114 GB from 32K to 512K and Splash 108–117 GB from 32K to 1M, against 90–110 GB for oMLX, MTPLX and ds4 at 128K. Close other large apps before a long session.

      5 · Splash up to 1M, and Swift 1.5

      Splash is Inco AI's inference engine on native Metal. It loads Flash-Next from a GGUF only: the base model as the unsloth UD-IQ4_XS, the Swift 1.5 fine-tune as the ukisai IQ4_XS. The tiles compare Swift 1.5 on Splash with the same fine-tune in MLX on mlx-serve 26.10.3, the stack I use every day. The gap belongs to the stack (runtime + weight format), not to the server alone.

      6.6 sper agent turn at 256K, against 9.2 s on mlx-serve
      6.7 sper agent turn at 512K, against 12.7 s on mlx-serve
      9.3 sper agent turn at 1M; mlx-serve fails some 1M requests
      25.5 minfirst message at 1M, nothing cached

      iQ-MLX and Swift 1.5 on the same mlx-serve build

      Up to 128K the two quants tie on 26.10.3. Past 128K, Swift 1.5 is faster: 12.7 s against 14.5 s at 512K. The iQ pack lost decode speed from 26.10.1 to 26.10.3, while Swift 1.5 gained.

      ContextiQ-MLX 4.7 bpw · mlx-serve 26.10.1iQ-MLX 4.7 bpw · mlx-serve 26.10.3Swift 1.5 · mlx-serve 26.10.3
      8K7.8 s84 tok/s7.9 s81 tok/s7.7 s84 tok/s
      32K8.2 s80 tok/s8.1 s82 tok/s8.0 s82 tok/s
      128K8.8 s74 tok/s8.9 s74 tok/s8.9 s74 tok/s
      256K9.8 s67 tok/s11.9 s57 tok/s9.2 s74 tok/s
      512K13.0 s56 tok/s14.5 s49 tok/s12.7 s57 tok/s

      3 runs per cell, except iQ on 26.10.1 at 256K and Swift 1.5 at 256K: 1 run. 512K uses YaRN 2.0 and the 4-bit KV cache on both builds.

      Swift 1.5 thinks less and scores the same

      Swift 1.5 is a community fine-tune that thinks less before it answers. On mlx-serve it scored the same as the base quant within the noise of these samples and reached the final answer 2.9× faster on GPQA and 2.0× faster on LiveCodeBench. Its agent turn time is the same, because prefill and the cache do not change.

      Median time to the final answers per question · lower is better

      Vendor sampling, reasoning effort xhigh, one run per model. Base: ddalcu iQ-MLX 4.7 bpw. Swift 1.5: Dankpaws/Swift1.5-Qwen3.8-Flash-Next-MLX-4.7bpw. The two packs also have different n-gram tables, so the comparison is between the packs, not only the fine-tune.

      Conclusion

      Use Splash 1.4.0 with the unsloth UD-IQ4_XS GGUF for the shortest agent turn. Use mlx-serve 26.10.3 with the ddalcu iQ-MLX 4.7 bpw quant when the history changes often.

      Splash had the shortest agent turn at every context size, from 8K to 1M, and it is the only server that served 1M. The cost is the cache: a change halfway in the history prefills the whole prompt again, 13 min at 512K against 8 min on mlx-serve. I did not check the quality of the base model on Splash. Among the MLX servers the runner-up is oMLX 0.7.0 (12.1 s at 128K), but it stops at 256K. With Swift 1.5, Splash is faster again (6.7 s at 512K, 9.3 s at 1M), and on mlx-serve 26.10.3 Swift 1.5 is the faster quant past 128K (same-build table).

      6.8 sper agent turn at 128K on Splash, against 8.9 s on mlx-serve
      7.3 sper agent turn at 512K on Splash, against 14.5 s on mlx-serve
      1.9 sto start the next reply at 512K on Splash, from cache (first message: 13 min)
      13 minafter a change halfway at 512K on Splash, against 8 min on mlx-serve

      6 · Run it yourself

      These are the flags I measured. The data, the prompt generator and the scripts behind this page are in the repository.

      Splash 1.4.0

      Download unsloth/Qwen3.8-Flash-Next-GGUF (UD-IQ4_XS, 94 GB) or ukisai/Swift-1.5-Qwen3.8-Flash-Next-GGUF (IQ4_XS, 98 GB). This is the 1M setting; for 256K or 512K, set --max-context to 262144 or 524288. Splash picks the DFlash2 draft model and the 8-bit KV cache by itself.

      Splash 1.4.0, base model UD-IQ4_XS, 1M

      splash serve --model unsloth/Qwen3.8-Flash-Next-GGUF:UD-IQ4_XS \
        --host 0.0.0.0 --port 8585 --max-context 1000000 \
        --revision 766911a6b7369840a91dbcd95f9f997acaab6cd6 \
        --idle-release off --language-only --no-webui --offline \
        --verify-rows auto

      Splash 1.4.0, Swift 1.5 IQ4_XS, 1M

      splash serve --model ukisai/Swift-1.5-Qwen3.8-Flash-Next-GGUF:IQ4_XS \
        --host 0.0.0.0 --port 8585 --max-context 1000000 \
        --revision 0142554c963a8653912c0c8283f05f13f63653f3 \
        --idle-release off --language-only --no-webui --offline \
        --verify-rows auto

      mlx-serve 26.10.3

      Download ddalcu/Qwen3.8-Flash-Next-MLX-Serve-iQ-MLX-4.7bpw (107 GB) and mlx-serve 26.10.3, which exposes OpenAI and Anthropic compatible endpoints. The prefix cache flags matter: with the default 2 GB cache, a 128K session read the whole prompt again on every turn. For 512K, use the 4-bit KV cache; with 8-bit, some long prompts did not fit in memory.

      Up to 256K (native context)

      mlx-serve --model ~/models/Qwen3.8-Flash-Next-MLX-Serve-iQ-MLX-4.7bpw \
        --serve --host 127.0.0.1 --port 11234 \
        --ctx-size 262144 --mtp --ssm-checkpoint-max 16 \
        --prefix-cache-mem 16GB --prefix-cache-disk 100GB --prefix-cache-entries 64

      512K (YaRN 2.0 + 4-bit KV cache)

      mlx-serve --model ~/models/Qwen3.8-Flash-Next-MLX-Serve-iQ-MLX-4.7bpw \
        --serve --host 127.0.0.1 --port 11234 \
        --ctx-size 524288 --mtp --ssm-checkpoint-max 16 \
        --prefix-cache-mem 16GB --prefix-cache-disk 100GB --prefix-cache-entries 64 \
        --kv-quant 4 --kv-attn-mode fused \
        --config-overrides '{"text_config":{"rope_parameters":{"rope_type":"yarn","factor":2.0,"original_max_position_embeddings":262144},"max_position_embeddings":524288}}'

      Tips for daily use

      7 · Quality sanity check

      Does a server or quant break the model? Not in these runs: the five stacks I checked are within a few cases of each other. One run per cell, on different dates, with a small sample. Read it as a sanity check, not as a ranking. ds4 and Splash with the base model were not checked.

      Context sizes differ: the three base-model stacks ran at 128K, the two Swift 1.5 stacks at 262K (the 262K columns of the table below). HumanEval with the prompt's import lines added before the answer; on Splash it ran twice at 262K (158 and 159 of 164) and the bar shows the first run. LiveCodeBench v6: 50 questions (seed 42), graded with the official import lines. Instruction following: 20 prompts with format constraints, an IFEval-style probe. Tool calls A = jdhodges tool-call test; tool calls B = Veerman tool-call test. mlx-serve with the iQ pack: 2026-10-11 run on 26.10.1; oMLX and MTPLX (with --memory-limit max): 2026-10-09 runs, without instruction following. The oMLX LiveCodeBench bar comes from a 2026-10-15 run of the same pack on oMLX 0.7.1.dev1; MTPLX was not measured. Swift 1.5 stacks: 2026-10-25 runs.

      Swift 1.5 on Splash, up to 1M

      TestSwift 1.5 · mlx-serve · 262KSplash · 262KSplash · 512KSplash · 1M
      HumanEval (164)158/164158/164 · 159/164156/164155/164 · 158/164
      GPQA-Diamond (50)43/5041/5043/5043/50
      LiveCodeBench v6 (50)47/5047/5047/5047/50
      Instruction following (20)19/2019/2018/2019/20
      Tool calls A (40)34/4037/4037/4036/40
      Tool calls B (12)10/1210/1210/129/12
      Long-context recall at the server's size (8)8/88/88/88/8

      One run per cell, vendor sampling, reasoning effort xhigh; each column starts the server at that context size. HumanEval with the prompt's import lines, as in the chart; it ran twice at 262K and 1M on Splash, and the 1M result is within the run-to-run noise. Long-context recall: 8 questions about a document filled to the server's size.

      8 · How I measured

      Test prompt
      A long audit document filled to the target size, with three facts hidden at 10%, 50% and 90% of the text. A reply is correct when it finds all three.
      Scenarios
      First message: the full prompt, no cache (cold prefill). Next turn: the same prompt plus a tool result at the end. User adds a message: the same prompt plus a new user message. History changes halfway: the prompt changes at its midpoint, so only the first half can be a cache hit.
      Agent turn time
      TTFT on the next turn + 512 ÷ median decode speed. It is the wait for one agent step with a 512-token reply.
      Runs
      One to three runs per point; the "Runs" column of the last table gives the number. A point with three runs shows the median.
      Speculative decoding
      The MLX servers and ds4 use the model's MTP head, a small extra head that drafts the next tokens; Splash uses a separate draft model (DFlash2). Output stays the same, decode gets faster.
      YaRN
      A method that stretches the model's position encoding beyond its native 262K tokens.
      Harness
      A script sends each scenario to the server's HTTP API and reads the timings from the stream. No coding agent sits in the loop.
      Which servers, when
      In October 2026 mlx-serve, oMLX, MTPLX and ds4 were the servers that ran Flash-Next on Apple Silicon with MTP and a prefix cache, each on its newest release (2026-10-07 to 2026-10-15). mlx-dspark 0.20.3 ran at 32K only and behind these four; llama.cpp, LM Studio and mlx-vlm were not measured. Splash 1.4.0 and Swift 1.5 on mlx-serve 26.10.3 ran from 2026-10-23 to 2026-10-25. On 2026-10-27 I ran the iQ pack again on 26.10.3, so both mlx-serve stacks on this page run the same build; the same-build table keeps 26.10.1 too.
      Data and scripts
      The raw results, the prompt generator and this page's script are in the repository (bench/engine-updates-2026-10, bench/swift15-flashnext-2026-10, bench/stack-updates-2026-10 and bench/splash-longctx-2026-10).

      What this page does not measure

      Setup notes

      All values

      One row per server and context size. Times in seconds (TTFT = time to first token). Decode and prefill in tokens/s, memory in GB.