GEMINI LABJP
SUNSET — Six days until the image generation models shut down: the imagen-4.0 family and Gemini 3 Image models stop on August 17MIGRATE — gemini-3.1-flash-image is the recommended replacement, and it means rewriting generate_images calls as generate_contentCHECK — The same prompt will not necessarily produce the same picture after migrating, so secure any images you still need before the cutoffCLASSROOM — August 17 is also the day Gemini in Classroom arrives on mobile; the web rollout to students of all ages began on August 10DEPRECATION — The Grok 4.1 family shuts down on August 20, and gemini-robotics-er-1.6-preview on August 31, succeeded by the er-2 modelsCHANGELOG — The Gemini API changelog still ends at July 30. The most recent major change remains the GA of Gemini 3.6 Flash and 3.5 Flash-LiteSUNSET — Six days until the image generation models shut down: the imagen-4.0 family and Gemini 3 Image models stop on August 17MIGRATE — gemini-3.1-flash-image is the recommended replacement, and it means rewriting generate_images calls as generate_contentCHECK — The same prompt will not necessarily produce the same picture after migrating, so secure any images you still need before the cutoffCLASSROOM — August 17 is also the day Gemini in Classroom arrives on mobile; the web rollout to students of all ages began on August 10DEPRECATION — The Grok 4.1 family shuts down on August 20, and gemini-robotics-er-1.6-preview on August 31, succeeded by the er-2 modelsCHANGELOG — The Gemini API changelog still ends at July 30. The most recent major change remains the GA of Gemini 3.6 Flash and 3.5 Flash-Lite
Articles/API / SDK
API / SDK/2026-07-29Advanced

A 17% Drop in Output Tokens Sounded Big. Then I Decomposed the Bill

Output pricing fell 16.67% and output tokens fell about 17%. Adding those numbers does not give you the savings. Here is an exact price/volume/cross-term decomposition, plus a loop measurement where the savings rate went down instead of up.

Gemini API208Cost EngineeringToken AccountingAgents8Operations10

Premium Article

When Gemini 3.6 Flash quietly replaced the Flash model I was calling in the week of July 21, the first thing I did was arithmetic in my head.

Output pricing moving from $9.00 to $7.50 per million tokens. Call it 16.67% off. On top of that, reports of roughly 17% fewer output tokens for the same work.

So, about 33% cheaper.

I rewrote a budget sheet for my automation pipelines on that assumption, and the numbers refused to line up. Some pipelines showed a tenth of the savings I had penciled in.

Two mistakes. I had added two factors that needed to be multiplied. And I had ignored the fact that input pricing did not move at all.

What follows is the decomposition I wrote to clear both up, and the output of actually running it. Prices are the ones published as of July 2026 — they change, so verify against primary sources before you make a call.

When price and volume move together, the order of subtraction matters

Output cost is unit price times quantity. Price goes $9.00 to $7.50, quantity goes 1.00 to 0.83, and the cost lands at 7.50 × 0.83 = 6.225.

That is a 30.84% reduction, not the 33.67% you get by adding.

The missing 2.83 points is the overlap: the discounted price is being applied to the tokens that no longer exist. Double-counted savings.

Economists call this the cross term, and it shows up any time you attribute a change in a product of two factors. It is not small enough to wave away.

from dataclasses import dataclass
 
@dataclass(frozen=True)
class Price:
    name: str
    inp: float   # USD / 1M input tokens
    out: float   # USD / 1M output tokens
 
OLD = Price("gemini-3.5-flash", 1.50, 9.00)
NEW = Price("gemini-3.6-flash", 1.50, 7.50)
 
def cost(p: Price, ti: int, to: int) -> float:
    return (ti / 1_000_000) * p.inp + (to / 1_000_000) * p.out
 
def decompose(old_p: Price, new_p: Price, to_old: int, to_new: int):
    """Split the output-side delta into price / volume / cross effects.
    The three must sum to the observed delta, up to floating point noise."""
    q0, q1 = to_old / 1_000_000, to_new / 1_000_000
    p0, p1 = old_p.out, new_p.out
    price_effect = (p1 - p0) * q0          # move price only
    volume_effect = (q1 - q0) * p0         # move quantity only
    cross = (p1 - p0) * (q1 - q0)          # the part that moved together
    total = p1 * q1 - p0 * q0
    residual = abs((price_effect + volume_effect + cross) - total)
    if residual > 1e-9:
        raise AssertionError(f"decomposition does not close: residual {residual}")
    return price_effect, volume_effect, cross, total

The residual assertion is there because attribution formulas break silently. Adjust one term later and the identity stops holding without any visible symptom.

Three workloads through the same decomposition

I collapsed my own traffic into three shapes — input-heavy, output-heavy, and balanced — and ran them. These are program outputs, not invoice figures.

WorkloadInput tokensOutput tokensOutput share of old billTotal savings
A Classification batch (input-heavy)2,000,00040,00010.7%3.30%
B Draft generation (output-heavy)30,000120,00096.0%29.60%
C Conversation (balanced)200,00060,00064.3%19.82%

Same model, same 17% reduction, and the bill moves anywhere from 3.30% to 29.60%.

Workload A breaks down as $3.3600 before, $3.2490 after. The −$0.11100 delta is a −$0.06000 price effect, a −$0.06120 volume effect, and a +$0.01020 cross term.

Note the sign on that cross term. When price and quantity fall together, the cross term pushes back against the savings. That is precisely why the additive estimate always errs on the optimistic side.

And A stalls for a structural reason: output is only 10.7% of the bill. The other 89.3% is input at an unchanged $1.50. Most of the spend sits where the discount never lands.

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
Adding 16.67% and 17% gives 33.67%; composing them correctly gives 30.84% — the 2.83-point gap traced to the cross term with runnable code
The same 17% reduction produces 3.30% savings on an input-heavy classification batch and 29.60% on output-heavy drafting
A 12-turn agent loop where savings fell from 20.40% to 15.59%, and history pruning that beat the model switch at 26.9%
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-07-18
Keeping a Long-Running Managed Agent Alive Across Sandbox Recycling — Durable Checkpoints and Idempotent Resume
A Managed Agents sandbox can be recycled out from under you. Before 40 minutes of work resets to zero, we design a durable checkpoint that pushes progress outside the sandbox and an idempotent resume that never runs a side effect twice. With working SQLite code.
API / SDK2026-07-14
When a Batch Job Sat in RUNNING for Half a Day: Field Notes on Catching Stalls Early with Per-State Dwell Budgets and Record Reconciliation
When a Gemini Batch job stalls quietly under the shadow of the 24-hour SLA, per-state dwell-time budgets and submitted-vs-completed record reconciliation let you name the stall early. Field notes with real operational numbers.
API / SDK2026-07-01
Keeping Unattended Jobs From Failing Silently: A Preflight Gate for Gemini's Platform Changes
Unrestricted API keys are now rejected, the old CLI reached end of life, and the Interactions API is becoming the default entry point. These 2026 platform shifts stop working automation without raising an error. Here is a preflight gate, with runnable code, that catches the failure before the batch runs.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →