Reasoning
Controlling thinking depth, output volume, and latency.
The model thinks before it answers. The thinking arrives in
message.reasoning_content, the answer in message.content, and the
amount of thinking is the main lever on both latency and output volume,
because reasoning counts toward the tokens generated.
Setting the effort
{
"model": "cf-chat",
"messages": [{"role": "user", "content": "..."}],
"chat_template_kwargs": {"reasoning_effort": "low"}
}| value | effect |
|---|---|
{"reasoning_effort": "low"} | the default if you send nothing |
{"reasoning_effort": "medium"} | more thinking, more output tokens |
{"reasoning_effort": "xhigh"} | deepest available |
{"enable_thinking": false} | skips reasoning entirely |
Only those four are accepted; anything else returns
400 Unexpected reasoning effort. In particular high is not valid
even though xhigh is, and neither are max, minimal or none.
Output caps and reasoning do not mix
A max_tokens cap is only unsafe with reasoning on: the reasoning is
emitted first and spends the budget, and a request that hits the cap
returns HTTP 200 with finish_reason: "length" and truncated content,
with no error to catch. How much content survives depends on how much
the model decided to think: it can be a partial answer or nothing at
all. One measured example where the reasoning consumed the entire cap:
max_tokens=256 content: 0 chars reasoning: 1150 chars
max_tokens=256 + enable_thinking:false content: 1170 chars reasoning: 0 charsIf you need bounded output, pair the cap with
{"enable_thinking": false}. Otherwise leave the cap off: the endpoint
imposes no ceiling and the model stops when it is finished.
What to expect
Worth calibrating before you point real workloads at it:
a one-line question ~1,500 output tokens, most of it reasoning
per-request generation rate ~60 tokens/second
6 concurrent realistic requests 11 to 17 seconds eachOutput length is unbounded by design, so latency and volume scale with
how much the model decides to think. reasoning_effort is the control;
enable_thinking: false is the floor.
Prefix caching
A shared prompt prefix is cached, and a cache hit skips prefill entirely. In our measurements a stable ~2,000-token prefix cut time-to-first-token by roughly 100 ms against an uncached one.
If you have a fixed system prompt or tool schema, keeping it byte-identical across requests is worth doing and costs nothing. The block size and exact hit rates are still being characterised, so do not pad prompts to a specific length yet; firmer numbers will follow.