Code execution and Google Search grounding (Gemini)
Gemini ships three first-party “server tools” — Python code_execution, google_search grounding, and url_context — that run on Google’s infrastructure when you enable them, rather than client-side functions you implement. All three are enabled by adding a Tool entry to the request and require zero implementation work on your side. The model decides when to use them, executes them in-flight, and folds results back into its generation, returning the trail (executed code, search citations, fetched URLs) in the response so you can render or audit. Together they make agentic Gemini workflows possible without you wiring up a sandbox, a search API, or a fetcher.
See also
- tool-use-and-function-calling-gemini — sibling for custom function calling
- gemini-models-and-capabilities — grounding-cost change between 2.5 and 3.x
- vision-and-long-context-gemini — file-based input for code execution
- computer-use-and-code-execution — sister doc on Claude server-tools
- tool-use-and-function-calling-openai — OpenAI’s hosted-tool equivalents (web search, code interpreter)
1. Code execution
Enabling
from google import genai
from google.genai import types
resp = client.models.generate_content(
model="gemini-3.5-flash",
contents="What is the 50th Fibonacci number? Compute it.",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())],
),
)The model decides when to write + run Python. The response includes the code, the execution result, and the natural-language interpretation as separate parts.
Inspecting the trail
for part in resp.candidates[0].content.parts:
if part.text:
print(f"TEXT: {part.text}")
elif part.executable_code:
print(f"CODE ({part.executable_code.language}):")
print(part.executable_code.code)
elif part.code_execution_result:
print(f"RESULT ({part.code_execution_result.outcome}):")
print(part.code_execution_result.output)outcome values: OUTCOME_OK, OUTCOME_FAILED, OUTCOME_DEADLINE_EXCEEDED, OUTCOME_UNSPECIFIED.
Sandbox details
Per ai.google.dev/gemini-api/docs/code-execution (2026-05):
| Property | Value |
|---|---|
| Language | Python only (model can generate other languages as text, but only Python executes) |
| Max execution time | 30 seconds per code block |
| Memory | Sandbox-limited (no documented exact value; ~few GB) |
| Network | No external network access (cannot make HTTP requests) |
| Filesystem | Ephemeral; can read input files passed to the model |
| Pre-installed libraries | NumPy, Pandas, Matplotlib, scikit-learn, TensorFlow, PyTorch, SymPy, SciPy, OpenCV, Pillow, fpdf, reportlab, statsmodels, BeautifulSoup, requests (won’t reach external), 30+ others — see docs for current list |
| Custom packages | Cannot install (pip install not available) |
Visualization
Matplotlib output is captured as an image and included in the response:
for part in resp.candidates[0].content.parts:
if part.inline_data and part.inline_data.mime_type.startswith("image/"):
# Plot image bytes available in part.inline_data.data
with open("plot.png", "wb") as f:
f.write(part.inline_data.data)Other visualization libraries (Plotly, Seaborn) can render but only Matplotlib’s image capture is documented to round-trip back.
File input to code execution
You can pass files (PDF, CSV, image, audio) and the code can read them:
csv_file = client.files.upload(file="data.csv")
resp = client.models.generate_content(
model="gemini-3.5-flash",
contents=[
"Load this CSV with pandas and show summary stats. Make a histogram of column 'price'.",
csv_file,
],
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())],
),
)File input ~1-2 MB max in this context (token-window constrained). For larger CSVs, sample first.
Billing
Per the docs: no additional charge for enabling code execution. Token usage:
- Original prompt → input tokens
- Generated code + execution result → intermediate tokens (billed as output)
- Summary + final answer → output tokens
A run that generates 500 tokens of code + 2,000 tokens of result + 300-token summary costs ~2,800 output tokens. At Gemini 3.5 Flash’s $9 / MTok output, that’s ~$0.025 per code run.
When code execution helps vs hurts
Helps:
- Exact math (Fibonacci, primes, statistics) — model is unreliable without execution
- Data analysis on provided CSV / JSON
- Chart generation
- Algorithm verification
- Calendar / date arithmetic
- Unit conversions at precision
Hurts (per the docs caveat — “Enabling code execution can lead to regressions in other areas of model output”):
- Simple Q&A — model may unnecessarily write code to “be sure”
- Latency-sensitive UI — code execution adds seconds
- Creative writing — code distracts the model
Practical: enable for analytical / quantitative tasks; disable for chat / creative / generative.
2. Google Search grounding
Enabling
resp = client.models.generate_content(
model="gemini-3.5-flash",
contents="What's the latest news on the SpaceX Starship test?",
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())],
),
)The model decides when to search. Returns a normal text response plus groundingMetadata documenting the searches and sources.
Response structure
gm = resp.candidates[0].grounding_metadata
print(gm.web_search_queries) # ["spacex starship test 2026", ...]
for chunk in gm.grounding_chunks:
if chunk.web:
print(chunk.web.uri, chunk.web.title)
for support in gm.grounding_supports:
print(support.segment.start_index, support.segment.end_index,
support.grounding_chunk_indices, support.confidence_scores)
print(gm.search_entry_point.rendered_content) # HTML widget to displayFields:
web_search_queries— the queries the model actually issued (often paraphrases of the user prompt)grounding_chunks— sources, each withweb.uri(URL) andweb.titlegrounding_supports— links text spans in the response to source indices, with confidence scoressearch_entry_point.rendered_content— an HTML/CSS snippet to render the “Search suggestions” widget (required to display by Google’s grounding terms)
Rendering citations
Walk grounding_supports and inject footnote markers:
text = resp.candidates[0].content.parts[0].text
supports = sorted(gm.grounding_supports, key=lambda s: s.segment.end_index, reverse=True)
for s in supports:
cites = ",".join(str(i+1) for i in s.grounding_chunk_indices)
text = text[:s.segment.end_index] + f"[{cites}]" + text[s.segment.end_index:]Then render the chunks list as a footnotes section.
Search widget requirement
Per Google’s grounding terms, when you display grounded output you must render the searchEntryPoint.renderedContent HTML widget (clickable “Search suggestions” chips that link to Google Search). The widget is provided pre-styled. Compliance requirement, not optional.
Billing — major change at Gemini 3
Per ai.google.dev/gemini-api/docs/pricing 2026-05:
| Model generation | Billing model |
|---|---|
| Gemini 3.x | Per-query: each search the model decides to execute is one billable unit ($14 / 1,000 queries on paid tier, after the 5,000 monthly free queries on Gemini 3) |
| Gemini 2.5 and older | Per-prompt: any request that triggered grounding counted as one billable use, regardless of how many sub-searches happened |
Practical impact: a single Gemini 3 prompt that triggers 5 searches now costs 5× a single Gemini 2.5 prompt with the same searches. Heavy agentic loops can hit grounding costs much faster on 3.x. Budget for it; consider routing pure factual Q&A to grounding-free models when freshness isn’t critical.
Quota / free tier
- Gemini 3 models: 5,000 grounded queries / month free on paid tier
- Beyond free: $14 per 1,000 queries
- Gemini 2.5 / older: per-prompt — cheaper for heavy use
Best practices
- Use grounding when you need fresh information (post-training-cutoff events, current prices, breaking news)
- Don’t use grounding for evergreen knowledge — it adds latency + cost for no benefit
- Inspect
groundingMetadata.grounding_supports[].confidence_scores— low confidence (< 0.5) suggests the claim is weakly supported - Render the
searchEntryPointwidget (compliance)
3. URL context tool
A separate hosted tool for fetching specific URLs without going through Google Search.
resp = client.models.generate_content(
model="gemini-3.5-flash",
contents="Compare the documentation at https://example.com/a and https://example.com/b.",
config=types.GenerateContentConfig(
tools=[types.Tool(url_context=types.UrlContext())],
),
)The model fetches the URLs (HTML rendered to text/markdown) and uses them in the response. Returns url_context_metadata listing the fetched URLs and statuses.
When to use vs grounding
| Need | Tool |
|---|---|
| Fresh information, no specific source | google_search |
| Compare / summarize specific URLs you know | url_context |
| Both | Enable both — they can be combined |
URL context is also useful for “follow this link the user gave me” — the user provides URLs, the model fetches.
Limits
- Max URLs per request: ~20 (observed; not strictly documented)
- Max content per URL: token-window-bounded (~1M total context)
- Failed fetches (404, paywall) surface in
url_context_metadatawith status
4. Combining tools
config=types.GenerateContentConfig(
tools=[
types.Tool(function_declarations=[my_custom_tool]),
types.Tool(google_search=types.GoogleSearch()),
types.Tool(code_execution=types.ToolCodeExecution()),
types.Tool(url_context=types.UrlContext()),
],
)Limitations on combinations as of 2026-05:
- Code execution + grounding — supported. The model can search for context, then execute code on the findings.
- Code execution + function calling — supported, but the model occasionally gets confused choosing between executing code itself vs calling out. Be explicit in the system prompt.
- Grounding + structured output (
response_schema) — may not be supported simultaneously. Test for your use case; fall back to grounding-only with a manual structuring pass.
5. Cost summary across tools
| Tool | Per-invocation cost (beyond standard tokens) |
|---|---|
code_execution | $0 — pay only for tokens consumed |
google_search (Gemini 3) | $14 / 1,000 queries (after 5,000 free / month) |
google_search (Gemini 2.5) | per-prompt (lower for heavy use) |
url_context | $0 — pay only for tokens consumed |
| Custom function | $0 — your function runs on your infra |
6. Comparison to other vendors
| Capability | Gemini | Claude | OpenAI |
|---|---|---|---|
| Hosted Python sandbox | code_execution — 30s, no net, Python | code_execution_* tool — 60s, opt-in libs | Code Interpreter on Assistants / Responses |
| Web search grounding | google_search — Google index | web_search_* tool | Web Search hosted tool |
| URL fetch | url_context | web_fetch_* tool | (via tools or custom) |
| Server-side billing surcharge | Search only ($14/1k on 3.x) | Search $10/1k | Search add-on, varies |
| Combination friendliness | Mostly free to mix | Mostly free to mix | Some restrictions on Assistants vs Responses |
7. Common pitfalls
- Forgetting to render
searchEntryPoint— compliance violation under Google’s grounding terms. Always render. - Cost surprise on Gemini 3 grounding — agentic loop triggers 10 searches per turn × 20 turns = 200 queries = ~$2.80 per session. Budget.
- Code execution timeout — 30s is short for matrix-heavy workloads. Pre-compute / cache when possible.
- No package install — code execution can’t
pip install. If your task needs an exotic library, switch to a custom function calling out to your own sandbox. - Grounding + structured output — combination is fragile; do them in two passes.
url_contexton auth-required URLs — fetcher has no cookies / OAuth. Fails on private content.- Searches that the model doesn’t execute — model may decline to search if it thinks it knows the answer. Force with system prompt instructions like “Always search for current information about
” or use a function-call tool. - Code that executes destructive ops — sandbox prevents actual harm (no filesystem persistence, no network), but generated code can
os.removefiles passed in. Treat input files as ephemeral.
8. Further reading
- Code execution — sandbox details, libraries, examples
- Grounding with Google Search — grounding metadata, citations
- URL context tool — fetching specific URLs
- Pricing — Search grounding — per-query rates
- Google grounding terms — display requirements