All Articles
Empty Output but finish_reason Is MAX_TOKENS on Gemini 2.5/3: Cause and Fix
Your prompt is just a few lines, yet a low maxOutputTokens on gemini-2.5-flash returns empty text with finish_reason MAX_TOKENS. The culprit is thinking tokens. Here are three fixes with working code.
Mixing Gemini 2.5 Flash and Flash-Lite for App Store Localization
An operations log from running the same wallpaper-app store copy through both Gemini 2.5 Flash and Flash-Lite. Real cost gaps, where the lighter model breaks down, and how I now route by text type and locale.
Measuring the Economics of Each Gemini-Powered Feature — So You Can Keep It, Fix It, or Retire It
Gemini API costs are visible at the account level, but the profitability of an individual feature never shows up on its own. This guide shows how to tag every request, build a per-feature cost ledger, join it with revenue signals from AdMob and in-app purchases to compute contribution margin, and decide whether to keep, fix, or retire each feature — with the code I actually run.
Why Gemini API Throws 'Unsupported MIME type' and How to Fix It
The 'Unsupported MIME type' error from the Gemini API has three distinct causes: a misspelled MIME string, an octet-stream upload, and a genuinely unsupported format. Here is how to tell them apart with code that actually works.
Bulk Processing Without the 429s: Adaptive Concurrency for the Gemini API
Pushing tens of thousands of requests through the Gemini API with a fixed concurrency almost always produces 429s and dropped items. Here is an AIMD design that auto-tunes concurrency from the 429 feedback, with a bounded worker pool, a dead-letter queue, and resumable checkpoints.
Localizing App Store Keyword Fields with Gemini 2.5 Flash — A Month of Notes Across 40 Apps
Operational notes from a month of using Gemini 2.5 Flash to draft the 100-character App Store keyword field across 40 wallpaper apps and several locales — CJK character counting, deduping against the title, prohibited terms, per-locale quirks, and what actually moved the needle.
Preserving Gemini 3 Thought Signatures So Multi-Turn Function Calling Doesn't Degrade
When you build function calling on Gemini 3 thinking models, reasoning quality often drops from the second turn onward. The cause is usually a dropped thought signature. Here is how to keep it and verify the effect.
Why Gemini 2.5 Pro Rejects thinkingBudget: 0 (and How to Fix It)
Setting thinkingBudget to 0 on Gemini 2.5 Pro returns a 400 INVALID_ARGUMENT error. Here is why the per-model thinking budget ranges differ, how to minimize thinking on Pro the right way, and when to switch to Flash, with Python and JavaScript examples.
Two Months of Turning App Store Connect Daily Sales into a Slack Digest with Gemini 2.5 Flash
Notes from two months of running App Store Connect Sales/Trends data through Gemini 2.5 Flash and posting a short morning digest to Slack. Why Flash beat Pro for this job, how AdMob and store revenue stopped colliding, and what a single 'normal/check' label changed.
Propagating a Time Budget Through a Multi-Stage Gemini Pipeline
A field memo on killing DEADLINE_EXCEEDED errors in an in-app help search by carrying a single request-wide deadline through the embed, search, and generate stages — sizing maxOutputTokens from the remaining budget and reserving a fallback budget so a breach returns a partial answer instead of an error.
Designing a Semantic Clustering Pipeline for App Reviews with Gemini Embeddings
How I cluster 10,000+ app reviews from my indie apps using Gemini Embeddings to compute improvement priorities. The three-layer pipeline and cost design that emerged from a year of running it.
Why HTTP Referrer Restrictions on Your Gemini API Key Cause 403 Errors in Production
Walks through why a Gemini API key with HTTP referrer restrictions can suddenly return 403 PERMISSION_DENIED in production. Covers the exact referrer string format, SDK behavior differences, how to safely route around the limitation with a tiny edge proxy, and how it differs from the CORS error you hit when calling straight from the browser.