TL;DR: We ran the same two-bug fix through MiniMax M3.1 Flash at all five effort levels plus "omitted", three runs each, and graded every answer against 215 hidden tests. Every run passed. The omitted default, which MiniMax documents as max, averaged 6,364 thinking tokens, 56 seconds, and $0.0045 per fix. low averaged 591 thinking tokens, 9.5 seconds, and $0.0006. So the default cost about 7× low and bought nothing on this task. Set low explicitly and move up per task.
The engineering problem: M3.1 Flash always thinks, and if the request has no effort field, MiniMax's text generation guide says it "defaults to max". Code migrated from MiniMax M2.x never set an effort level because M2.x had none. That code now runs at the most expensive setting by default.
Setup
- Model:
minimax-m3.1-flashon AIHubMix. Upstream reportsMiniMax-M3.1-Flash. - Endpoint:
POST https://aihubmix.com/v1/chat/completions,max_tokens: 32768, key fromAIHUBMIX_API_KEY(see the AIHubMix quick start). - Date: 19 October 2026. Three runs per setting.
- Prices (AIHubMix, per 1M tokens): $0.165 input, $0.66 output, $0.0165 cached input. Thinking tokens bill as output.
The task: a billing function with two bugs. A pause that runs past the period end double-counts one day, and overlapping pauses get subtracted twice. The prompt states both symptoms and asks for the corrected function in one code block. A local harness runs it against 215 cases: 15 hand-written edge cases plus 200 random ones checked against a brute-force reference. The original buggy function passes 138.
Field names per protocol
| Protocol | Field | Values | Default |
|---|---|---|---|
| OpenAI Chat Completions | reasoning_effort | low, medium, high, xhigh, max | max |
| Anthropic Messages | output_config.effort | low, medium, high, xhigh, max | max |
| OpenAI Responses | reasoning.effort | low, medium, high, xhigh, max | max |
All three protocols work for this model on AIHubMix. Thinking can't be turned off. MiniMax's Messages API reference says thinking: {"type": "disabled"} and effort none return HTTP 400 with model "MiniMax-M3.1-Flash" requires adaptive thinking. Older MiniMax models ignore the effort field.
The measurement loop
This is the shape of the run, minus the grader:
import os, time
from openai import OpenAI
client = OpenAI(base_url="https://aihubmix.com/v1", api_key=os.environ["AIHUBMIX_API_KEY"])
prompt = open("bugfix_prompt.md").read()
for effort in [None, "low", "medium", "high", "xhigh", "max"]:
for run in range(3):
extra = {"reasoning_effort": effort} if effort else {}
t0 = time.time()
r = client.chat.completions.create(
model="minimax-m3.1-flash", max_tokens=32768,
messages=[{"role": "user", "content": prompt}], **extra)
u = r.usage
print(effort or "omitted", run, round(time.time() - t0, 1),
u.completion_tokens, u.completion_tokens_details.reasoning_tokens)
Results
| Effort | Avg thinking tokens | Range (3 runs) | Avg time | Avg cost per fix | Tests |
|---|---|---|---|---|---|
| low | 591 | 344–812 | 9.5 s | $0.0006 | 215/215 ×3 |
| medium | 1,522 | 970–2,488 | 21.7 s | $0.0013 | 215/215 ×3 |
| high | 2,863 | 2,194–3,673 | 27.1 s | $0.0022 | 215/215 ×3 |
| xhigh | 1,949 | 1,019–2,562 | 19.2 s | $0.0015 | 215/215 ×3 |
| max | 4,699 | 2,612–6,246 | 40.4 s | $0.0034 | 215/215 ×3 |
| omitted | 6,364 | 4,284–9,376 | 56.3 s | $0.0045 | 215/215 ×3 |
Cost arithmetic for the "omitted" row: 464 prompt tokens, about 192 of them cached, plus 6,673 output tokens. That's (272 × $0.165 + 192 × $0.0165 + 6,673 × $0.66) ÷ 1M ≈ $0.0045.
What the table supports:
-
Quality was flat. 18 Chat runs, 18 perfect fixes. On this bounded bug, thinking beyond
lowbought nothing measurable. - low → medium is a real step: about 2.6× the thinking tokens and more than twice the time.
- Above medium, n=3 can't order the levels. xhigh averaged below high, and max overlaps both.
- Omitted ≈ max, as documented. The higher "omitted" average is within run-to-run noise.
- Time tracks tokens. Throughput held at about 112 output tokens per second across all 24 Flash runs (Chat and Messages), so a 6,000-token think costs close to a minute of wall time.
Short prompts behave differently. With five support tickets sorted into four labels, low used 0 thinking tokens and the default averaged 6, with every label correct. "What is 17 × 23?" at low produced no thinking and 2 output tokens. Adaptive thinking scales with the prompt, so the missing off switch barely costs anything on classification-style calls.
Failure modes and fixes
Truncation from thinking. Thinking counts toward max_tokens. One default run used 9,376 thinking tokens on a single function. A 4K or 8K limit carried over from M2.x can end with finish_reason: "length" and a cut-off answer. Fix: raise max_tokens (MiniMax recommends 131,072, max 524,288) and check finish_reason.
Latency spikes at a fixed level. On the Anthropic Messages endpoint, three low runs used 511, 1,861, and 6,060 thinking tokens; the last took 56 seconds. Effort sets the average depth, not a cap. Fix: set client and proxy timeouts to 120 s or more at high and above, and don't size timeouts from low averages alone.
Effort values that silently do nothing. Through AIHubMix, reasoning_effort values none, minimal, and auto all returned HTTP 200, and the model still thought. MiniMax's own endpoints reject unknown values, according to a gateway project's tests (sub2api issue #8025). Fix: send one of the five documented values. AIHubMix's unified reasoning parameters page describes how the gateway maps reasoning fields across vendors.
Tools that don't send a level. OpenCode resolves no effort variants for this model, so its effort toggle does nothing. Some frameworks also send "thinking disabled", which returns the 400. Fix: check the outgoing request body.
Mixed-model routing. M3 and M2.x ignore the effort field, so a level that saves money on Flash does nothing on the others.
Verify it reached the model. Read usage: completion_tokens_details.reasoning_tokens (Chat), output_tokens_details.thinking_tokens (Messages), output_tokens_details.reasoning_tokens (Responses). If these don't change when you change the level, the setting isn't arriving.
Setting it on Messages and Responses through AIHubMix:
import os
import anthropic
from openai import OpenAI
ant = anthropic.Anthropic(base_url="https://aihubmix.com", api_key=os.environ["AIHUBMIX_API_KEY"])
msg = ant.messages.create(
model="minimax-m3.1-flash", max_tokens=32768,
messages=[{"role": "user", "content": "Write a function that merges overlapping date ranges."}],
extra_body={"output_config": {"effort": "medium"}},
)
print(msg.usage)
oai = OpenAI(base_url="https://aihubmix.com/v1", api_key=os.environ["AIHUBMIX_API_KEY"])
resp = oai.responses.create(
model="minimax-m3.1-flash", reasoning={"effort": "low"}, max_output_tokens=32768,
input="Write a function that merges overlapping date ranges.",
)
print(resp.usage)
Starting points
Only the first two rows are backed by the measurements above. The rest are recommendations to check against your own retry rates.
| Workload | Start at | Move up when |
|---|---|---|
| Classification, extraction, routing | low | Labels are wrong on hard cases |
| Single-function fixes, small reviews | low | A fix fails tests twice |
| Multi-file changes, refactors | medium | The agent misses a dependent file |
| Agent loops with many tool calls | low or medium | Steps repeat or stall |
| Hard debugging, design questions | high | Answers stay shallow |
| Interactive chat, person waiting | low | Never default to max here |
What we can't verify
-
Where higher levels start to pay off. Our task was solved at every level. MiniMax hasn't published per-level token, latency, or accuracy data, and one bounded task can't show where
high,xhigh, ormaxearn their cost. - Ordering above medium. Three runs per level isn't enough to separate high, xhigh, and max.
- Other tasks and prompt lengths. All numbers come from one short coding prompt and one classification prompt, measured by AIHubMix on 19 October 2026. Nobody else has reproduced them.
Keep reading: the MiniMax M3.1 Flash series
- For the bigger picture behind this setting, from the Space Bunny launch to the price against M2.7 and M3: MiniMax M3.1 Flash (ex-Space Bunny) on the API: Specs, Price, and a Measured Bug-Fix Cost
- Effort is one of several things that change when M2.5/M2.7 code moves over. This post covers the 400 errors and the rest: Fixing "requires adaptive thinking" (2013) When Moving from MiniMax M2.7 to M3.1 Flash
- At
low, Flash was the cheapest of three models on this same fix. Here's how its default compares with DeepSeek's and Haiku's: MiniMax M3.1 Flash vs DeepSeek V4.1 Flash vs Claude Haiku 5.5: Same Bug Fix, Measured
Top comments (0)