ASK KNOX
beta
LESSON 293

Thinking Mode in Production

Thinking mode is not a quality dial you leave at maximum — it is a deliberate routing decision with latency and cost consequences that you must own.

9 min read·Building with Gemini

Every Gemini model that supports thinking mode will try to think, given the chance. That is not a feature — it is a cost and latency multiplier you need to consciously control. Understanding when thinking mode earns its overhead, and when it quietly burns your budget for no return, is the difference between operators and users.

How Thinking Mode Works

On Gemini 2.5 Pro and 2.5 Flash, thinking is on by default — the model generates a chain-of-thought reasoning block before producing the final answer whether you configure anything or not. Two separate controls matter, and operators routinely confuse them:

  • thinking_budget controls whether and how much the model thinks. It caps the reasoning tokens; setting it to 0 disables thinking entirely on Flash (Pro cannot be fully disabled — its minimum budget is 128 tokens).
  • include_thoughts=True controls visibility only. It returns summaries of the reasoning in the response so you can inspect them. It does not enable thinking — thinking happens (and is billed) either way.

The model works through the problem systematically: considering alternatives, testing assumptions, catching contradictions, before committing to an answer.

The key structural difference when thoughts are included: the response returns multiple content parts. Some parts are tagged as thought: True — these are the reasoning summaries. The remaining parts are the final answer. Your code needs to handle both.

from google import genai
from google.genai import types

client = genai.Client()

response = client.models.generate_content(
    model='gemini-2.5-pro',
    contents="You have three switches outside a room. One controls a light bulb inside. You can only enter the room once. How do you determine which switch controls the bulb?",
    config=types.GenerateContentConfig(
        thinking_config=types.ThinkingConfig(include_thoughts=True)
    )
)

for part in response.candidates[0].content.parts:
    if part.thought:
        print(f"[THOUGHT]: {part.text}")
    else:
        print(f"[ANSWER]: {part.text}")

The output separation matters for production systems. If you are logging responses for debugging, logging the full response including thoughts gives you visibility into how the model arrived at the answer. If you are passing the answer to a downstream system, you need to filter to non-thought parts only.

Which Models Support Thinking Mode

As of April 2026:

  • Gemini 2.5 Pro — full thinking mode support, GA
  • Gemini 2.5 Flash — thinking mode support, GA
  • All Gemini 3.x models — thinking mode support, Preview

Thinking mode is not available on Gemini 2.0 Flash, Lite models, or any Nano variant. If you are routing to a model that does not support thinking and pass ThinkingConfig, the parameter is ignored — you do not get an error.

Controlling Spend with thinking_budget

Uncapped thinking can generate a reasoning block that is 2-3x the length of your input prompt. For a complex task with a 2,000-token input, that means 4,000-6,000 thinking tokens before the model writes a single word of its answer.

The thinking_budget parameter caps the maximum thinking tokens:

response = client.models.generate_content(
    model='gemini-2.5-pro',
    contents=prompt,
    config=types.GenerateContentConfig(
        thinking_config=types.ThinkingConfig(
            include_thoughts=True,
            thinking_budget=1024  # cap thinking at 1K tokens
        )
    )
)

Setting a budget forces the model to reason within a constraint. The output quality at low thinking_budget values degrades gracefully — the model still reasons, just more efficiently. At very low budgets (under 256 tokens), you are essentially suppressing thinking for all but the simplest reasoning chains.

Because 2.5 models think by default, disabling thinking is an explicit act — and it is the mechanism behind the "off by default" operator workflow:

# Disable thinking on Flash for a high-volume, cost-sensitive call
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents=prompt,
    config=types.GenerateContentConfig(
        thinking_config=types.ThinkingConfig(thinking_budget=0)
    )
)

thinking_budget=0 fully disables thinking on Flash and Flash-Lite. Gemini 2.5 Pro cannot have thinking disabled — its minimum budget is 128 tokens, so for Pro you cap rather than eliminate the overhead.

For production use:

  • Complex reasoning tasks: thinking_budget=20484096
  • Moderate tasks: thinking_budget=5121024
  • Structured extraction where thinking is a hedge: thinking_budget=256, or thinking_budget=0 on Flash to disable entirely

When Thinking Mode Earns Its Cost

Thinking mode genuinely improves output quality on a specific class of tasks:

Multi-step reasoning problems. Anything that requires holding a constraint set across multiple reasoning steps — logic puzzles, sequential planning, constraint satisfaction. The model checks its own work in a way that single-pass generation does not.

Ambiguous prompts with multiple valid interpretations. When a prompt could reasonably be answered in several ways, thinking mode helps the model surface and evaluate the interpretations before committing. You get a more considered answer, not just the first plausible one.

Complex code debugging. When a bug requires tracing execution state across multiple functions or evaluating several hypotheses about the failure mode, thinking mode produces more systematic analysis. The thoughts reveal what assumptions the model tested and eliminated.

Mathematical and quantitative reasoning. Multi-step calculations, proof construction, and any task where an arithmetic error early in the chain corrupts the final answer benefit from the self-checking that thinking mode enables.

Strategic planning with competing priorities. Situations where the model needs to weigh tradeoffs and justify a recommendation benefit from thinking mode. The reasoning is visible and auditable, which is useful in regulated or high-stakes contexts.

When Not to Use Thinking Mode

The majority of API calls do not need thinking mode. Enabling it universally is the most common and expensive mistake operators make after learning about it.

Simple classification. If you are labeling sentiment, categorizing documents, or assigning tags from a fixed list, the model does not need to reason through multiple paths. Single-pass generation is faster and cheaper with no quality loss.

High-volume, low-latency pipelines. Thinking adds latency — typically 1-3 additional seconds on complex prompts, sometimes more. If your pipeline processes thousands of requests per hour and response time matters, thinking mode is the wrong tool.

Structured data extraction from consistent formats. If the input format is predictable and the extraction schema is well-defined, thinking mode adds no value. The model does not need to reason about how to extract fields from a JSON blob.

Cost-sensitive workloads. Thinking tokens are billed at the standard rate for the model. A 50M-token monthly budget that runs cleanly on non-thinking calls can be exhausted 3-4x faster once you enable thinking universally — because each call now carries thousands of reasoning tokens on top of its input and answer.

Thinking Tokens and Caching

Thought tokens interact with the prompt cache differently from standard input tokens. The thinking block is generated fresh on each request — it is not cached from a previous call, even if the prompt is identical. This means caching your system prompt or static context does not offset thinking token costs.

If you are relying on prompt caching to reduce costs on a high-context task, and you add thinking mode, expect your cost savings from caching to be partially eroded by the uncached thinking overhead.

Reading Thoughts for Debugging

One underused production benefit of thinking mode: visibility into the model's reasoning when outputs are wrong. If a non-thinking call produces an incorrect answer, you have no insight into why. If a thinking-enabled call produces an incorrect answer, the thought block shows you exactly where the reasoning went wrong.

For tasks where correctness is critical and you are willing to pay the overhead, logging thought blocks to your observability layer gives you a debugging signal that has no equivalent in standard generation. You can see which assumptions the model made, which alternatives it considered and rejected, and where the reasoning chain broke down.

This is particularly valuable during the development and validation phase of a new pipeline, even if you disable thinking in the production steady state.