Newsletter
Join the Community
Subscribe to our newsletter for the latest news and updates

Eight tests, two MiniMax models, one fictional rental shop.
Lists of "top AI writing tools" usually compare apps: their templates, their editors, their monthly plans. Underneath most of those apps sits a language model reached through an API, and for a small team building its own workflow, the model is the part that decides quality, speed and cost. So instead of reviewing another app, we tested the engine directly.
Our test subject was MiniMax M3, the newest general-purpose model in MiniMax's text family, with the older M2.5 alongside it for comparison. Both are reasoning models: they think before they answer, and that thinking turned out to be the most important thing to understand about them. We ran eight jobs that a small content team does every week, wrote scripts to score every answer, and recorded the time, the token counts, and the bill. The 48 completed requests cost 16 cents in total.
The scenario is fictional. Larkspur Trails is an invented hiking-gear rental shop with a two-person content team. Every input below, from the product specs to the meeting transcript, was written for this test, and every output is quoted exactly as the model returned it.
Both models use the standard chat completions format, so any OpenAI-compatible client works. We called them through an API gateway that lists both at the same price: $0.24 per million input tokens and $0.96 per million output tokens. That price matters more than usual here, because reasoning tokens are billed as output tokens even though you never see them. Here is the core of our test harness, with the host kept in an environment variable:
import os, time, requests
BASE = os.environ["LLM_API_BASE"] # any OpenAI-compatible /v1 endpoint
H = {"Authorization": "Bearer " + os.environ["LLM_API_KEY"]}
PRICE_IN, PRICE_OUT = 0.24, 0.96 # USD per million tokens
def ask(model, messages, **kw):
t0 = time.time()
r = requests.post(f"{BASE}/chat/completions", headers=H, timeout=900,
json={"model": model, "messages": messages, **kw}).json()
u = r["usage"]
reasoning = u.get("completion_tokens_details", {}).get("reasoning_tokens", 0)
cost = (u["prompt_tokens"] * PRICE_IN + u["completion_tokens"] * PRICE_OUT) / 1e6
return {"text": r["choices"][0]["message"]["content"],
"seconds": round(time.time() - t0, 1),
"reasoning_tokens": reasoning, "cost": cost,
"finish": r["choices"][0]["finish_reason"]}
out = ask("minimax-m3", [{"role": "user", "content": "Summarise this call: ..."}])Logging reasoning_tokens separately from completion_tokens is the single most useful line in that function. Without it, you cannot explain why two answers of the same length cost ten times as much. We also wrapped every call in a retry loop. During our run, a handful of M2.5 requests were cut off by dropped connections before any answer arrived; we re-sent those, and the numbers below come from completed responses only.

Both models followed the format. Only one stayed inside the spec sheet.
Product copy is the classic AI-writing job, and the classic failure is a confident sentence about a feature the product does not have. We gave each model four rental items with a short spec line, for example "freestanding dome tent, 2.1 kg, two doors, 3000 mm waterproof fly, rental 14 USD per day", and the same instruction every time:
Write a product description for our rental website. Rules: 50 to 60 words; second person (address the reader as 'you'); must contain the exact phrase 'free returns'; no exclamation marks; do not invent features that are not in the spec; plain text only, no headings, no bullet points.
On the format rules, both models scored perfectly. All eight descriptions landed between 51 and 56 words, all addressed the reader as "you", all contained "free returns", and none used an exclamation mark. That is a good result for a word-count rule, which older models often missed by 20 percent or more.
The difference was in the last rule. M3 stayed strictly inside the spec in all four descriptions. Its tent copy reads: "The Cirrus two-person tent is a freestanding dome tent that weighs 2.1 kg and features two doors for convenient access. Its 3000 mm waterproof fly helps protect your shelter from the weather." Plain, accurate, slightly dry. M2.5 was livelier and less careful. Its tent was "easy-to-pitch" and "the simple design lets you set up in minutes"; its sleeping bag had a "compact design" that "fits easily in your pack"; its backpack "keeps you comfortable on long hikes". None of that was in the spec. For a rental shop, "set up in minutes" is a promise a customer can hold you to. We counted invented claims in three of M2.5's four descriptions and none in M3's.
The time and cost were very different too. M3 needed 8 to 11 seconds per description; M2.5 needed 45 to 131 seconds. Both spent most of their output on reasoning: M3 used 600 to 1,300 reasoning tokens to write about 70 visible tokens, M2.5 used 1,100 to 2,100. Each description still cost only $0.0007 to $0.0021.

The shorter of two M3 summaries, with the 12 facts we checked for.
Meeting summaries fail quietly: a summary that reads well but drops the one number someone needs is worse than no summary. We wrote a 440-word transcript of a weekly operations call at the shop, with stock shortages, a discount decision, a refund backlog and four action items, and planted 12 facts we could check automatically: figures such as 312 orders, 61 reservations against 40 tents, a 10 percent single-use code, a lost 2,400 dollars, 57 open tickets, a 180-dollar repair, plus each owner and deadline. The prompt asked for at most eight bullets, every number, and every action item with owner and deadline.
M3 ran twice and found all 12 facts both times, in six and seven bullets. It also got the subtle points right: the new refund message was quoted word for word, "refund started, usually arrives in 3 to 5 business days", and in the second run it even noted that one task had no deadline in the transcript instead of making one up. The runs took 19.6 and 10.3 seconds and cost $0.0029 and $0.0015. The longer run was not better; it simply reasoned longer, 2,401 reasoning tokens against 1,022, which shows how much the cost of an identical request can vary.
M2.5 needed 403 seconds and 2,542 reasoning tokens for the same summary, and used all eight allowed bullets. A first pass of our checker reported two missing facts, but they were there: M2.5 had written "10 %" and "3‑5" with a non-breaking space and a non-breaking hyphen, which a plain text search does not match. If summaries feed another script, normalise Unicode spaces and dashes first. The more serious problem was a quiet change of meaning. The transcript says the extra tents arrive "Thursday at the earliest"; M2.5 wrote that the supplier "will deliver 25 extra Cirrus tents by Thursday". That turns a risk into a promise, exactly the kind of error a reader who missed the call cannot catch.

Five fields per email, scored against our own labels.
Structured output is where a writing model becomes an automation tool. We wrote eight short customer emails, some tidy and some messy ("order no. lt 20391 - one of the trekking poles won't lock"), and asked for a JSON object with five fields: order id in the format LT-NNNNN, item, issue type from a fixed list of eight, whether a refund was requested, and sentiment. The schema went in the system message.
Every answer from both models was valid JSON with no extra text, which is the first thing that breaks in a pipeline. M3 matched our labels on 38 of 40 fields when sent one email at a time. Both differences were sentiment: we had labelled the wrong-size backpack email and the "is everything ok?" pickup email as neutral, and M3 called both negative. That is a judgement call, not an error, and it is a good reminder to define labels like sentiment precisely if they drive anything. M3 normalised the messy "lt 20391" to "LT-20391" correctly.
M2.5 matched 39 of 40 fields and agreed with our neutral label on both of the emails M3 called negative. Its one miss was format: it returned "LT20402" without the hyphen, even though the schema spelled out the pattern, so a strict validator would have rejected it. M2.5 was also slower, 10 to 58 seconds per email against M3's 3 to 6 seconds.
We then sent all eight emails to M3 in a single request and asked for a JSON array. It returned a valid array of eight objects in 7.6 seconds, scored 39 of 40, and cost $0.0010, against $0.0015 for eight separate calls. Batching small extraction jobs is cheaper because the instructions are sent once, and with this model it did not cost any accuracy.

All runs found all three planted facts and refused to invent the fourth.
Long context is what lets a writing assistant work from a whole handbook instead of a pasted paragraph. We generated a dull, realistic document, a gear-condition log with thousands of lines like "Item Cirrus tent #412 checked on 2026-03-14 by Rosa: condition minor wear, rentals to date 37...", and hid three policy notes in it, at 10, 50 and 90 percent of the way through: the price of gas canisters, a resin cleaning fee and who is exempt, and the time and price of a trailhead shuttle. We added a fourth question whose answer was not in the document at all: the late-return fee for kayaks.
M3 answered all four correctly at 29,000 tokens (7.1 seconds, $0.007) and at 114,000 tokens (10.5 seconds, $0.028). It answered the trick question with "not in the document", exactly as instructed, and did not borrow a fee from elsewhere in the log. M2.5 also scored four of four at 114,000 tokens, in 25.6 seconds. Its first attempt at this request hung for a long time and ended in a dropped connection, so for very long inputs a generous timeout and a retry policy are not optional.
The cost line is worth a second look. At this price, reading 114,000 tokens costs under three cents, and nearly all of that is input. If a support assistant needs the full handbook on every question, that is affordable; if it answers thousands of questions a day, retrieving only the relevant sections will still save real money. For teams comparing options, the MiniMax LLM API lists M3 and M2.5 at the same per-token price, so the choice between them comes down to speed and accuracy rather than rate cards.

Same 200-word request, several runs per model.
For anything interactive, a chat panel or an editor plug-in, the user waits for the first visible word. We streamed the same request repeatedly, a 200-word welcome email for new customers, and measured when the first token of any kind arrived and when the first visible word arrived.
The first token of any kind arrived quickly and consistently: 2.4 to 3.8 seconds for M3 and 2.6 to 7.3 seconds for M2.5. But that first token is reasoning, which a chat interface does not show. The first visible word is what users wait for, and that varied enormously. Across four complete M3 runs, the first word of the email appeared after 11, 13, 21 and 59 seconds; the slow run had spent 7,287 tokens thinking about a 200-word email, against 906 to 1,602 in the others. M2.5 was slower in every run: 72, 178, and 265 seconds to the first word in its three complete runs, with 4,918 to 9,247 reasoning tokens. A fourth M2.5 run streamed 643 reasoning tokens and then ended without writing anything at all. One thing both models did with uncanny precision was length: six of the seven finished emails were exactly 200 words by our count, and the seventh was 207.
The practical consequence: a streaming interface built on a reasoning model should show that something is happening during the thinking phase, for example, a "drafting" indicator, because the screen will otherwise stay blank for longer than users tolerate. And if you have a fixed latency budget, measure it on several runs, not one.

Both rewrites are easy to read. Only one kept every rule.
Rewriting for a different audience is a daily task for content teams. Our source was a single 87-word sentence from a rental policy, written in the style of a contract, with a Flesch-Kincaid grade of 38, which is a statistical way of saying "unreadable". We asked for a version a 12-year-old could follow, under 70 words, keeping every rule.
Both models produced text at roughly a fifth-grade level: 5.6 for M3 and 5.1 for M2.5. M3 used 68 words, just under the limit, and kept every condition, including the one that matters most to the shop: the late fee is waived "only if Larkspur Trails decides the delay was outside your reasonable control". M2.5 was shorter, 48 words, and lost exactly that clause. Its version says "If something outside your control delays you, call the store before the deadline and give proof if asked", which reads as if the waiver were automatic. In a policy, simplification that changes who decides is not simplification; it is a different policy. Readability scores cannot catch that, only a reader comparing the meaning can.

Most of the bill for the blog draft was thinking, not writing.
We asked for a 1,200-word post titled "How to choose a rental tent for your first backpacking trip", with Markdown subheadings, practical advice, no product names, and no exclamation marks.
M3 delivered 1,192 words, an almost exact hit, with eight logical sections from "Start with the conditions" to "Care for the tent before you return it", no product names and no exclamation marks. The advice is sensible and specific to renting, such as pitching the tent once in the shop before leaving, and the text has little of the repetition that long AI drafts often fall into: no three-word phrase appeared more than three times. It is a solid first draft that an editor could shape in twenty minutes.
The cost structure is the surprise. The draft took 104 seconds and 15,511 output tokens, of which 14,099 were reasoning. Only about 1,400 tokens were the article itself. The total was still only $0.015, or about 1.2 cents per thousand finished words, but 91 percent of what we paid for was invisible planning.
M2.5 failed this test outright, and the way it failed is worth knowing. Our first attempt was cut off by a dropped connection. The second ran for 660 seconds and stopped with finish_reason "length" after 20,480 output tokens, every one of them reasoning, and returned an empty answer. We were billed $0.020 for nothing. Reading the reasoning trace showed why: after planning the sections, the model began drafting the article inside its thinking and counting its own words one at a time, "Check(79) the(80) floor's(81) denier(82)...", until it ran out of budget. The instruction to hit 1,200 words seems to have pushed it into verifying the count instead of writing. For long-form work with a reasoning model, give a range ("about 1,100 to 1,300 words") rather than an exact number, and set a hard timeout so a runaway request does not hold a worker for eleven minutes.

A limit that works for a non-reasoning model can silently break a reasoning one.
Many writing tools set max_tokens to keep costs predictable, and a common habit is to set it a little above the expected answer length. We asked for a 250-word welcome email with max_tokens set to 150, a limit that would at least have produced a truncated email from an older model.
M3 returned an empty string. It spent 149 of its 150 tokens reasoning, hit the limit, and stopped with finish_reason "length" before writing a single visible word. We were still billed for the 150 tokens. M2.5 spent 71 tokens reasoning and then wrote 79 tokens of an email before being cut off mid-sentence. Its draft also opened with an exclamation-heavy "Welcome to Larkspur Trails!" style, which our other prompts had forbidden but this one had not.
The lesson is the most practical one in this article. With reasoning models, max_tokens limits thinking plus answer, so a limit sized for the answer alone can produce nothing at all. Either leave generous headroom, several thousand tokens for short tasks, or check finish_reason and treat "length" with empty content as a failure to retry, not as an empty answer to publish.
The video below goes through the eight tests and the charts in under three minutes.
Walkthrough: MiniMax M3 and M2.5 on eight writing tasks (about 3 minutes).

Billed tokens, reasoning included, divided by the words we actually received.
| Test | Completed requests | Time per request | Cost |
|---|---|---|---|
| 1. Product descriptions | 8 | 8–131 s | $0.011 |
| 2. Meeting summaries | 3 | 10–403 s | $0.007 |
| 3. Email to JSON | 17 | 3–58 s | $0.005 |
| 4. Long-document lookup | 3 | 7–26 s | $0.062 |
| 5. Streaming latency | 8 | 13–269 s | $0.033 |
Forty-eight completed requests cost 16 cents. Two line items dominate: the long-document test, where 114,000 input tokens per run add up, and the two answers that reasoned the longest, the M3 blog draft and the M2.5 draft that never arrived. Per thousand finished words, M3 cost between $0.009 for the meeting summaries and $0.021 for the short policy rewrite; the shorter the output, the higher the share of thinking in the bill. M2.5 was more expensive per word in every task we could compare, $0.031 for product copy and $0.034 for the welcome emails, because it reasoned longer for the same result. At these prices, cost is not a reason to choose one model over the other. Time and accuracy are.
As a writing engine, MiniMax M3 did the jobs a small content team cares about, and did them carefully. It followed format rules exactly, stayed inside the facts it was given, kept every number in a summary, returned clean JSON, found three facts in a 114,000-token document and admitted when the answer was not there, and wrote a 1,200-word draft in 1,192 words. The older M2.5 matched it on format and retrieval but invented product features, changed the meaning of a policy and a delivery date, and was several times slower, once spending eleven minutes and two cents on an empty answer. The main thing to plan for with both is that they think before they write. That thinking makes first words slow and costs unpredictable from run to run, and a token limit sized for the answer alone can return nothing. Log reasoning tokens, leave headroom in max_tokens, check finish_reason, and show users that something is happening while the model plans. With those habits in place, M3 is an inexpensive and dependable engine for the writing tasks most AI writing tools are built around.
| 6. Plain-language rewrite | 2 | 11–41 s | $0.003 |
| 7. Blog draft | 2 | 104–661 s | $0.035 |
| 8. max_tokens limit | 2 | 4–9 s | $0.0004 |
| Total, including 3 connection checks | 48 | $0.16 |