GEMINI LABJP
NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaplyOMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflowsAGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactionsMEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuouslyTHROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and regionDEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Articles/API / SDK
API / SDK/2026-05-19Advanced

Wiring Circuit Breakers and Graceful Degradation into Gemini API — an Indie App's Stability-First Notes

When you run Gemini API in production for an indie app, something upstream breaks at least a few times a month. Here are the building blocks for circuit breakers and graceful degradation I settled on, with the implementation traps I actually hit.

Gemini API192Circuit Breaker2AvailabilityProduction32Architecture9

Premium Article

Around 2 AM on a night in late March 2026, a phone notification told me my crash rate had spiked. I opened Crashlytics and traced it to a chain of 503 responses from the Gemini API, followed by the main thread dutifully waiting out a 30-second timeout. AdMob impressions sagged in real time; that night alone, ad revenue ended up at less than half my usual figure. The app itself was fine, but a few minutes of upstream weather had punched a hole in the daily revenue. The next morning I sat down and rebuilt the circuit breaker and graceful degradation design more seriously. This piece is my notes from that rebuild and the tuning I have done since.

Why an Indie App Should Stop Aiming for "Always Working"

I have been shipping smartphone wallpaper apps and visualization apps as an indie developer since 2014, and the catalog has now passed 50 million cumulative downloads. As an indie developer Hirokawa, operations are basically a team of one. Even with Cloudflare Workers and CDN layers in front, an upstream provider like Gemini API will eventually have a few minutes that ripple through to the user.

So I gave up on a different goal. Instead of "Gemini API always answers", I aim for "the app stays quietly useful even in the seconds Gemini API does not answer". A nominal 99.9% availability sounds great, but it leaves you about 43 minutes of allowed downtime per month, and for an indie developer that 43 minutes is almost guaranteed to land on the weeknight evening when ads are actually clicking. The thing worth defending is not perfect uptime, it is the user experience during those minutes.

Circuit breakers and graceful degradation are the concrete tools for that mindset. Over 14 months since I shipped this design, upstream-triggered fatal crashes across my three main apps fell by 87% in Crashlytics, and the depth of revenue dips during incidents shrank noticeably.

Minimum Viable Circuit Breaker — Skeleton First

Plenty of libraries exist, but for an indie app the best insurance is "code I can fully explain to myself in one sitting." Here is the minimum Python skeleton I run server-side. While request volume is modest this is enough on its own.

import time
from dataclasses import dataclass, field
from enum import Enum
from threading import Lock
 
class State(str, Enum):
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half_open"
 
@dataclass
class Breaker:
    failure_threshold: int = 5          # consecutive failures to OPEN
    recovery_seconds: float = 30.0      # OPEN until HALF_OPEN
    half_open_max_calls: int = 3        # trial calls allowed
    state: State = State.CLOSED
    fail_count: int = 0
    opened_at: float = 0.0
    half_open_calls: int = 0
    lock: Lock = field(default_factory=Lock)
 
    def allow_request(self) -> bool:
        with self.lock:
            if self.state == State.OPEN:
                if time.time() - self.opened_at >= self.recovery_seconds:
                    self.state = State.HALF_OPEN
                    self.half_open_calls = 0
                else:
                    return False
            if self.state == State.HALF_OPEN:
                if self.half_open_calls >= self.half_open_max_calls:
                    return False
                self.half_open_calls += 1
            return True
 
    def on_success(self) -> None:
        with self.lock:
            self.fail_count = 0
            self.state = State.CLOSED
            self.half_open_calls = 0
 
    def on_failure(self) -> None:
        with self.lock:
            self.fail_count += 1
            if self.state == State.HALF_OPEN or self.fail_count >= self.failure_threshold:
                self.state = State.OPEN
                self.opened_at = time.time()
                self.fail_count = 0

The skeleton is under 60 lines. What matters in production is choosing failure_threshold and recovery_seconds against your real traffic shape. My wallpaper app backend runs around 4–12 req/s, so 5 consecutive failures (about a second of bad weather) into OPEN, with a 30-second cooldown, is my current resting point.

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
How to pick Closed/Open/Half-Open thresholds for an indie app's traffic shape
A four-stage fallback (Gemini 3 Pro → 2.5 Flash → cache → default text) with working code
A retry budget pattern that protects p95 latency instead of inflating it
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-06-26
When your Gemini API spend cap trips, paying users go down too — isolating the blast radius with per-tier projects
A Project Spend Cap stops the entire project at once. To keep a runaway free tier from taking paying users down with it, this is a design note on isolating the cap's blast radius across per-tier projects and closing the ~10-minute delay with an application-side soft budget gate.
API / SDK2026-05-31
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.
API / SDK2026-04-26
Architecting a Multi-Tenant SaaS on Gemini API — Tenant Isolation, Usage Metering, and Runaway Cost Defense in Production
A field-tested blueprint for serving Gemini API to multiple tenants on a single backend — covering tenant isolation choices, per-tenant rate limiting in Redis, request-level usage metering for billing, and runaway-cost defenses.
📚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 →