◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 6 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/API / SDK
◈ API / SDK/2026-05-14Advanced

Controlling thinking_budget in Gemini 2.5 Pro — Cut Costs by 70% Without Sacrificing Reasoning Quality

Leaving thinking_budget unset in Gemini 2.5 Pro leads to unexpected costs. This guide covers task-level budget design, dynamic control, and production monitoring with working Python code.

gemini-api286thinking-budgetgemini-2.5-pro13cost-optimization30indie-dev48python108

✦ Premium Article

For an indie developer, API cost management is not a theoretical concern — it is a constraint that shows up as a monthly bill, and a mismanaged one can quietly threaten whether a service stays alive at all.

I found this out the hard way when I integrated Gemini 2.5 Pro into one of my apps shortly after its release. The first week's API bill came in at over three times what I had projected. The culprit: I had left thinking_budget unset, and the model was spinning up thousands of thinking tokens on requests that didn't need them at all.

This guide covers how thinking_budget actually works, how to build a task classifier that sets it dynamically, what the cost savings look like in real numbers, and how to add monitoring before things get out of hand.

Why Leaving thinking_budget Unset Is a Costly Mistake

Gemini 2.5 Pro runs an internal chain-of-thought process before producing its final response. The tokens consumed during this process are thinking tokens, and thinking_budget is the parameter that caps how many can be used per request.

The documentation says you can set it to 0 to disable thinking entirely. What it does not make entirely clear is what happens when you omit it. Based on my own testing in May 2026, omitting the parameter allows the model to automatically use up to the maximum budget — currently around 24,576 tokens per request.

A simple sentiment classification request — "is this review positive or negative?" — can trigger thousands of thinking tokens under the default behavior. Since thinking tokens are billed at a rate comparable to output tokens, this accumulates quickly across thousands of daily requests.

The Billing Structure That Makes This Matter

Gemini 2.5 Pro bills across three categories:

  • Input tokens — the text you send in
  • Output tokens — the final response the model generates
  • Thinking tokens — internal reasoning tokens (not included in the output)

Thinking tokens are billed at roughly the same rate as output tokens. This means if your final response is 150 tokens but 4,000 thinking tokens ran behind the scenes, your effective cost for that request is nearly 27x what the output tokens alone would suggest.

Checking Your Current Usage

Before changing anything, check how many thinking tokens your current requests are actually using:

import google.generativeai as genai
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
 
model = genai.GenerativeModel("gemini-2.5-pro")
 
# Run a representative sample request WITHOUT thinking_budget set
response = model.generate_content(
    "Classify the sentiment: 'The delivery was late but the product quality is excellent.'"
)
 
if hasattr(response, "usage_metadata"):
    meta = response.usage_metadata
    thinking_tokens = getattr(meta, "thoughts_token_count", 0) or 0
    output_tokens = meta.candidates_token_count or 0
    print(f"Output tokens:   {output_tokens}")
    print(f"Thinking tokens: {thinking_tokens}")
    print(f"Ratio:           {thinking_tokens / max(output_tokens, 1):.1f}x")

Expected output (uncontrolled):

Output tokens:   32
Thinking tokens: 4817
Ratio:           150.5x

If you see ratios above 10x on simple requests, you have a significant optimization opportunity.

Mapping Task Complexity to Budget Levels

Not every request needs the same reasoning depth. Through production use across several apps, I settled on a four-level classification:

  • Level 0 (thinking off, budget=0) — Purely mechanical tasks: JSON formatting, direct translations, template filling, simple lookups
  • Level 1 (light thinking, budget=1,024–4,096) — Basic judgment: sentiment analysis, category tagging, brief summarization
  • Level 2 (medium thinking, budget=8,192–16,384) — Multi-step reasoning: code debugging, business logic with multiple conditions, structured analysis
  • Level 3 (full thinking, budget=16,384–24,576) — Complex problem solving: architectural decisions, nuanced document analysis, creative planning

Setting thinking_budget: The Basic Pattern

import google.generativeai as genai
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
 
model = genai.GenerativeModel(
    model_name="gemini-2.5-pro",
    generation_config=genai.GenerationConfig(
        thinking_config=genai.types.ThinkingConfig(
            thinking_budget=4096  # Level 1: light thinking
        )
    )
)
 
response = model.generate_content(
    "Classify the sentiment of this review: 'Great product, fast shipping.'"
)
 
if hasattr(response, "usage_metadata"):
    meta = response.usage_metadata
    thinking_tokens = getattr(meta, "thoughts_token_count", 0) or 0
    print(f"Input tokens:    {meta.prompt_token_count}")
    print(f"Output tokens:   {meta.candidates_token_count}")
    print(f"Thinking tokens: {thinking_tokens}")

Expected output:

Input tokens:    28
Output tokens:   9
Thinking tokens: 211

One important nuance: thinking_budget is a ceiling, not a target. Setting budget=4096 does not mean 4,096 thinking tokens will be used — it means the model may use up to that many. If the model determines 211 tokens is sufficient, that is all it uses. This makes budget-setting a safe operation: you are not wasting tokens by setting a number higher than needed, you are simply allowing the model room to use more if it judges it necessary.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A four-level task classifier that assigns thinking_budget dynamically by request complexity
✦A three-tier Flash / Pro-light / Pro-full routing strategy and how to judge each setting
✦Production monitoring, weekly reports, and pre-flight batch cost estimation that keep spend predictable
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

◈ API / SDK2026-05-18
Building Automatic Wallpaper Category Classification with Gemini Vision
An indie developer shares how they implemented automatic wallpaper image classification with the Gemini Vision API — including accuracy results, real pitfalls, structured-output tips, and a cost comparison with GPT-4o Vision.
◈ API / SDK2026-05-18
Gemini API asyncio Patterns for Production: How I Cut Processing Time by 80% in My Indie App Backend
A hands-on report on integrating Gemini API asyncio into a production backend. Covers Semaphore-based rate limiting, exponential backoff, partial failure handling, and what breaks when you move the same pipeline to the current google-genai SDK.
◈ API / SDK2026-05-17
Auto-generating Japanese and English Release Notes from git log with Gemini API — A Real Implementation from Beautiful HD Wallpapers v2.1.0
I realized I was spending 1–2 hours per release writing notes in multiple languages. Here's how I automated that with Gemini API and git log — tested on Beautiful HD Wallpapers v2.1.0, with code you can run today.