●NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaply●OMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflows●AGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactions●MEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuously●THROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and region●DEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20●NANOLITE — Nano Banana 2 Lite is here: Google's fastest and most cost-efficient Gemini Image model, made for running lightweight image generation cheaply●OMNIFLASH — Gemini Omni Flash is in public preview, a natively multimodal model that lets enterprises and developers build custom, dynamic video workflows●AGENTS — Managed Agents expand with background: true for async server-side runs and polling, remote MCP server integration, and refreshing credentials across interactions●MEMORY — The Memory Bank IngestEvents API is generally available, decoupling event ingestion from memory generation so you can stream content continuously●THROUGHPUT — Provisioned Throughput now lets you submit up to seven pending orders for the same model and region●DEPRECATE — Image generation models shut down on August 17, and the Grok 4.1 family on the Gemini Enterprise Agent Platform on August 20
Gemini API Context Caching— Cut Document Processing Costs by 90%
Learn how to use Gemini API's context caching to reduce repetitive document processing costs by up to 90%. Includes Python SDK implementation, caching strategies, and cost calculations.
When running Gemini API in production, the biggest cost driver is repeatedly sending large contexts. For instance, if you need to answer 100 questions about a 500-page technical manual, including the entire manual in every prompt leads to enormous token consumption.
Gemini API's Context Caching feature lets you cache large contexts once and reuse them across multiple requests, reducing input token costs by up to 90%.
What you'll learn:
How context caching works and its pricing model
Creating, using, and managing caches with the Python SDK
Cost optimization strategies for large document processing
Cache design patterns for production environments
How Context Caching Works
Basic Architecture
Context caching temporarily stores large contexts (documents, system prompts, code, etc.) on Google's servers. Subsequent requests reference a cache ID instead of re-sending the full context.
Standard request flow:
Request 1: [500-page manual] + Question 1 → Answer 1
Request 2: [500-page manual] + Question 2 → Answer 2
Request 3: [500-page manual] + Question 3 → Answer 3
→ Manual tokens are billed every single time
Context cache input tokens are priced at approximately 75% less than standard input tokens (as of March 2026).
Item
Standard Input
Cached Input
Savings
Gemini 2.5 Pro
$1.25/MTok
$0.3125/MTok
75%
Gemini 2.5 Flash
$0.075/MTok
$0.01875/MTok
75%
Note: MTok = 1 million tokens. Cache storage costs ($4.50/MTok/hour for Pro) apply separately.
✦
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
✦Cost optimization for Gemini API calls using Context Caching
✦Cost reduction patterns for large-scale text processing
✦Best practices for caching strategies
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.
# cache_setup.py — Creating a context cacheimport google.generativeai as genaifrom datetime import timedelta# Configure API keygenai.configure(api_key="YOUR_API_KEY")# Load the document to cachewith open("technical_manual.pdf", "rb") as f: pdf_data = f.read()# Create the cachecache = genai.caching.CachedContent.create( model="models/gemini-2.5-pro", display_name="Technical Manual v3.2", system_instruction=( "You are a technical manual assistant. " "Answer questions accurately based on the manual content. " "If information is not in the manual, explicitly state so." ), contents=[ genai.protos.Content( parts=[ genai.protos.Part( inline_data=genai.protos.Blob( mime_type="application/pdf", data=pdf_data, ) ) ], role="user", ) ], ttl=timedelta(hours=2), # 2-hour TTL)print(f"Cache created: {cache.name}")print(f"Token count: {cache.usage_metadata.total_token_count:,}")print(f"Expires: {cache.expire_time}")# Expected output:# Cache created: cachedContents/abc123xyz# Token count: 328,450# Expires: 2026-03-24T18:00:00Z
Querying with a Cache
# cache_query.py — Running queries against a cached contextimport google.generativeai as genaigenai.configure(api_key="YOUR_API_KEY")# Create a model from the cachemodel = genai.GenerativeModel.from_cached_content(cached_content=cache)# Process multiple questions efficientlyquestions = [ "What's the resolution for error code E-201 in Chapter 3?", "List all new features added in version 3.2", "Summarize the troubleshooting flowchart", "What authentication method does the API endpoint use?", "What are the recommended performance tuning settings?",]for i, question in enumerate(questions, 1): response = model.generate_content(question) print(f"\n--- Question {i}: {question}") print(f"Answer: {response.text[:200]}...") print(f"Input tokens: {response.usage_metadata.prompt_token_count:,}") print(f" Cached: {response.usage_metadata.cached_content_token_count:,}")# Expected output:# --- Question 1: What's the resolution for error code E-201 in Chapter 3?# Answer: E-201 is a connection timeout error. Follow these steps to resolve it...# Input tokens: 328,480# Cached: 328,450 (← cached tokens billed at discount rate)
Concrete Cost Calculations
Scenario: Technical Manual Q&A Bot
Let's compare costs with and without caching under these conditions:
# multi_doc_cache.py — Caching multiple documents togetherimport google.generativeai as genaifrom pathlib import Pathfrom datetime import timedeltagenai.configure(api_key="YOUR_API_KEY")def create_multi_doc_cache(doc_paths: list[str], display_name: str, ttl_hours: int = 4): """Bundle multiple documents into a single cache""" parts = [] for path in doc_paths: file_path = Path(path) mime_type = { ".pdf": "application/pdf", ".txt": "text/plain", ".md": "text/markdown", ".py": "text/x-python", }.get(file_path.suffix, "text/plain") with open(path, "rb") as f: parts.append( genai.protos.Part( inline_data=genai.protos.Blob( mime_type=mime_type, data=f.read(), ) ) ) cache = genai.caching.CachedContent.create( model="models/gemini-2.5-pro", display_name=display_name, contents=[ genai.protos.Content(parts=parts, role="user") ], ttl=timedelta(hours=ttl_hours), ) print(f"Cache created: {cache.name}") print(f"Total tokens: {cache.usage_metadata.total_token_count:,}") return cache# Usagecache = create_multi_doc_cache( doc_paths=[ "docs/api_reference.pdf", "docs/architecture.md", "docs/changelog.txt", ], display_name="Project Documentation Bundle", ttl_hours=8,)# Expected output:# Cache created: cachedContents/def456uvw# Total tokens: 512,300
Where Caching Actually Pays Off
Context caching is not a feature that always lowers your bill. When I was testing a setup in my own indie projects, the first few days were actually cheaper without a cache. Requests were sparse, and the storage fee quietly piled up on its own.
Whether caching pays off comes down to a rough break-even point: divide the fixed cost (cache creation plus storage) by the savings per request.
# break_even.py — estimate the break-even point for cachingdef break_even_requests(doc_tokens: int, cache_hours: int) -> float: INPUT = 1.25 / 1_000_000 CACHED = 0.3125 / 1_000_000 STORAGE = 4.50 / 1_000_000 # Fixed cost: creation (one full input) + storage (for the TTL window) fixed = doc_tokens * INPUT + doc_tokens * STORAGE * cache_hours # Savings per request: full-input price -> cached price saved_per_req = doc_tokens * (INPUT - CACHED) return fixed / saved_per_reqfor h in (8, 4, 1): n = break_even_requests(328_450, cache_hours=h) print(f"TTL {h}h: ~{n:.0f} requests to break even")# Expected output:# TTL 8h: ~40 requests to break even# TTL 4h: ~23 requests to break even# TTL 1h: ~6 requests to break even
Because storage dominates the fixed cost, the shorter you keep the TTL, the lower the break-even point. Just remember that for validation work or sparse traffic, a longer TTL makes caching less favorable — keeping that in mind will stop you from misjudging when to cache.
My first attempts at creating a cache tripped on three things, none of which are obvious from the pricing table alone:
Minimum token threshold: Explicit caches have a per-model minimum token count, and passing a short document gets the creation rejected. Caching is effective for documents spanning hundreds of pages, but don't force a few-thousand-token passage into a cache.
Pinning the model ID: The model used at cache creation must match the model used at inference, or the cache won't be referenced. If you use an auto-upgrading alias, the cache silently becomes invalid the moment the model rolls over underneath you. Pin a versioned ID like models/gemini-2.5-pro to stay safe.
TTL expiry is silent: An expired cache lapses without raising an exception, and the next call falls back to full-context billing. Add a check that detects expiry and logs it, so you aren't caught off guard after the bill grows.
A Note from an Indie Developer
When I first started running a document Q&A setup in my own indie projects, I assumed a cache was simply "safe to leave on." A week of real usage broke that assumption: traffic was intermittent during testing, and the storage fee was the only thing doing any work.
So I split the operation in two. Keep the TTL short during the validation phase, and switch to a longer TTL only during the hours when traffic concentrates in production. That one change alone brought the monthly bill back to a visible, predictable level.
The other lesson was how much it helps to log cache-hit status every time. Recording cached_content_token_count from usage_metadata makes it immediately clear whether the cache is hitting as expected, or quietly being skipped because of a model-ID mismatch. Cost optimization, I've come to feel, is less about flashy moves and more about this kind of unglamorous, steady measurement.
Wrapping Up: Dramatically Reduce API Costs with Context Caching
This guide covered how to optimize costs using Gemini API's context caching:
How it works: Store large contexts server-side and reuse across multiple requests
Python SDK implementation: Complete code examples for creating, using, and managing caches
Cost savings: ~70% reduction at 100 questions/day, ~85% at 500 questions/day
Production best practices: TTL design, multi-document management, lifecycle management
For any workflow involving repeated processing of large documents, context caching is an essential optimization technique. For broader Gemini API cost management, see "[Gemini API Long Context Strategies Guide]((/articles/gemini-api/gemini-long-context-strategies)". For API fundamentals, check out "[Gemini API Advanced Tool Use Guide]((/articles/gemini-api/gemini-api-tool-use-advanced)".
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.