Skip to content

Grok's Max Output Tokens per Model

8 min read · updated August 11, 2026

Ask what Grok’s maximum output is and the honest answer is that xAI does not publish one per model. What it publishes is a parameter, a default, and a window the output has to fit inside — and those three determine the real ceiling.

The number that is not on the model card

xAI’s model pages document context window, modalities, supported features, region availability, rate limits and price. They do not document a maximum output length. That is a genuine difference from providers that publish a separate output cap per model, and it is worth stating plainly rather than filling the gap with a plausible-looking figure: this page will not tell you that grok-4.5 tops out at some specific number, because xAI has not said so.

That absence is itself informative. Where a provider publishes an output cap well below its context window, the cap is a real serving constraint. Where a provider publishes only a window and a request parameter, the design intent is that the parameter and the window are the limit.

If xAI later publishes per-model output ceilings on its model pages, those supersede everything on this page. Check the model page for the version you are calling before designing around a long generation.

The parameter and its default

The documented figure is a default on the request parameter. xAI’s API reference describes max_completion_tokens as an upper bound on visible output tokens, defaulting to 128,000. max_tokens is documented as deprecated in favour of it.

{
  "model": "grok-4.5",
  "messages": [ { "role": "user", "content": "..." } ],
  "max_completion_tokens": 1024
}

A default of 128,000 is unusually permissive, and the consequence is a different failure mode from the one people are used to. On APIs where the parameter is required or defaults low, forgetting it produces a truncated answer — annoying, visible, cheap. Here, forgetting it produces a request that is permitted to generate 128,000 output tokens. At grok-4.5’s documented $6.00 per million output tokens, a single runaway generation that actually ran to the default would cost about $0.77; at the above-200k rate of $12.00 it would be about $1.54. One request. In a retry loop, that is the shape of an incident.

So set max_completion_tokens explicitly on every request, at the length the feature actually needs. It is a cost control and a blast radius control, not a quality setting. This is the same discipline as the equivalent default elsewhere, and it is the opposite of Anthropic’s design, where the field is required and omitting it is an error.

Output shares the context window

The second bound is arithmetic. Prompt and completion live in the same window, so the most you can generate is the window minus what you sent:

available_output  ~=  context_window - prompt_tokens

grok-4.3    1,000,000 - 900,000 prompt  ->    ~100,000 output
grok-4.5      500,000 -  20,000 prompt  ->   ~480,000 output
grok-build-0.1 256,000 - 250,000 prompt ->     ~6,000 output

Those are derived from the published context windows in the context window table, with the assumption stated: nothing else occupies the window. In a real request tool definitions, retrieved search results and images all sit on the prompt side of that subtraction, so the available output is smaller than a mental model based on your visible prompt suggests.

The practical rule is to set max_completion_tokens from the smaller of what you need and what is left, and to compute what is left from the actual prompt_tokens the last response reported rather than from an estimate.

Reasoning tokens come out of the same budget

On a reasoning model the trace is generated before the answer, occupies the window, and is billed. xAI’s rate-limit documentation lists reasoning tokens as a distinct category consuming your tokens-per-minute allowance, and its reasoning guide notes that usage exposes reasoning_tokens and that reasoning cannot be disabled on models that do it.

The parameter is documented as bounding visible output tokens, which leaves the interaction between a small max_completion_tokens and a long trace as behaviour to verify rather than assume. The safe construction is to give a reasoning request meaningfully more headroom than the answer length suggests, and to lower reasoning_effort — documented values none, low, medium, high — when you want a shorter trace, rather than trying to squeeze it with the token cap. See the reasoning mode page.

Detecting the ceiling

Whichever bound you hit, the signal is the same field. finish_reason is length when generation stopped because a token limit was reached, and stop when it ended naturally or on a stop sequence. There is no separate “truncated” flag and no exception — a truncated answer is a 200 with a full body and one different string in it.

choice = response["choices"][0]
if choice["finish_reason"] == "length":
    # the answer is incomplete; do not parse it as JSON,
    # do not show it as final, and do not blindly retry at
    # the same limit
    ...

Two things follow. Anything that parses model output — JSON, a diff, a code block — must check finish_reason before parsing, because truncated JSON is invalid JSON and the parse error will be reported against the wrong cause. And in streaming, that field arrives on the final chunk for the choice, so a client that stops reading when the text looks finished never learns the answer was cut off. The full chunk shape is in the streaming format page.

The mid-stream shape of this failure is worth stating precisely, because it looks like success right up to the end. Content deltas arrive normally; the prose reads as though it is going somewhere; nothing errors. Then a final chunk carries finish_reason: “length” and the stream closes with [DONE]. If your client stops consuming when the visible text stops changing, or renders the accumulated buffer the moment the connection ends, it never reads the field that would have told it the answer was cut in half.

Why “just continue” is not a fix

The obvious response to a length finish is to ask for the rest. It is worth understanding why that works far less often than it sounds like it should, because a continuation loop is a common thing to build and an expensive thing to debug.

  • There is no resume. The API is stateless with respect to generation: nothing on xAI’s side is paused waiting to carry on. A continuation is a fresh request with the truncated output appended to the conversation, which means you pay for the entire prompt again, plus the partial answer as input. Two continuations on a long-context request can cost several times the original call — and on a prompt near 200k, each attempt may land in the higher pricing tier.
  • The seam is a guess. The model resumes from a boundary it did not choose. Mid-sentence and mid-token continuations produce duplicated clauses, a restated introduction, or a fresh paragraph that quietly abandons the sentence it was in.
  • Structured output cannot be resumed reliably. A truncated JSON object is not a prefix the constrained decoder can be restarted from through the public API — response_format constrains a whole response, not a completion of somebody else’s fragment. In practice, a truncated schema-constrained call has to be re-run, not continued. See structured output.
  • Retrying at the same limit repeats the failure. If the cap was the binding constraint, the same request with the same cap truncates in the same place, only now twice as expensively.

The fixes that actually work are upstream of the failure. Ask for less, in the prompt, with a stated length target — that reduces cost and latency at the same time. Raise max_completion_tokens deliberately, once you know the real distribution of output lengths rather than guessing at it. Or partition the work: ask for one section at a time against a plan you generated first, so each request has a natural end well inside the cap and the seams are ones you chose. That last option is more code and it is the only one that scales to output measured in tens of thousands of tokens.