How to Run Long-Running AI Tasks With Gemini Background Execution
Learn how to use Gemini Interactions API background execution to run deep research, complex reasoning, and multi-step agent tasks asynchronously, with polling, streaming reconnection, multi-turn chaining, and cancellation patterns.
Published on • August 5, 2026
AI Assistant

Introduction
For long-running tasks like deep research, complex reasoning, or multi-step agents, connection timeouts can suddenly interrupt standard HTTP requests, which typically close after about 60 seconds. If your application needs to drive a model that’s thinking through a hard problem for several minutes, a plain synchronous request simply won’t work.
The Gemini Interactions API solves this with background execution. By setting "background": true when you create an interaction, the task runs asynchronously on Google’s servers. The API immediately returns an interaction ID, which your client can use to poll for status, stream progress, or reconnect to a stream that was interrupted.
In this post we’ll cover how background execution works, how to create background interactions, how to retrieve results with polling or streaming, how to chain multi-turn conversations, and how to cancel or delete running interactions.
Why background execution matters
Standard HTTP requests have real, practical limits. If a model needs to browse the web, run code, orchestrate sub-agents, or perform deep research, the request can easily outlive a client’s connection timeout. Background execution decouples the task lifecycle from your client connection:
- The server keeps working even if your client disconnects.
- You get an interaction ID immediately, which is the handle for everything that happens next.
- You can poll, stream, or reconnect to the same interaction from anywhere.
- It’s supported for standard Gemini models (
gemini-3.6-flash,gemini-3.1-pro-preview) and Managed Agents likeantigravity-preview-05-2026.
Creating a background interaction
Starting a background interaction is a one-line change: set background to true.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.6-flash",
input="Write a guide on space exploration.",
background=True,
)
print(f"Created background interaction ID: {interaction.id}")
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: "gemini-3.6-flash",
input: "Write a guide on space exploration.",
background: true,
});
console.log(`Created background interaction ID: ${interaction.id}`);
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
-d '{
"model": "gemini-3.6-flash",
"input": "Write a guide on space exploration.",
"background": true
}'
How background execution works
When you create a background interaction, the task runs asynchronously on the server. The interaction transitions through various execution states:
in_progress: The server is actively executing the interaction (running code, researching, etc.).requires_action: The interaction paused and is waiting for client input (confirming a tool execution or answering a question).completed: The interaction finished successfully and output is available.failed: An error occurred during execution (tool failure, rate limits, etc.).cancelled: A client request stopped the execution.
Best use cases
Reach for background execution when:
- Agent executions need code execution, web browsing, or sub-agent orchestration (for example
antigravity-preview-05-2026). - Deep research runs via
deep-research-preview-04-2026ordeep-research-max-preview-04-2026, which can take several minutes. - Long reasoning tasks need thinking steps that exceed standard HTTP connection limits.
Retrieving results
You can obtain background interaction results using either polling or streaming.
Polling pattern (non-blocking)
Polling checks the interaction status periodically with non-blocking GET requests until it reaches a terminal state.
Python
import time
from google import genai
client = genai.Client()
interaction = client.interactions.get(id="YOUR_INTERACTION_ID")
while interaction.status == "in_progress":
time.sleep(5)
interaction = client.interactions.get(id=interaction.id)
if interaction.status == "completed":
print(interaction.output_text)
else:
print(f"Finished with status: {interaction.status}")
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
let interaction = await client.interactions.get("YOUR_INTERACTION_ID");
while (interaction.status === "in_progress") {
await new Promise(resolve => setTimeout(resolve, 5000));
interaction = await client.interactions.get(interaction.id);
}
if (interaction.status === "completed") {
console.log(interaction.output_text);
} else {
console.log(`Finished with status: ${interaction.status}`);
}
REST
curl -X GET "https://generativelanguage.googleapis.com/v1beta/interactions/YOUR_INTERACTION_ID" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Api-Revision: 2026-05-20"
Streaming pattern with reconnection
If a network interruption disconnects a stream, the stream can resume from the last received event. Each delta contains a unique event_id in its payload. Passing this ID as last_event_id resumes the stream from that event.
Python
import time
from google import genai
client = genai.Client()
interaction_id = "YOUR_INTERACTION_ID"
def stream_with_reconnect(interaction_id: str):
last_event_id = None
while True:
try:
# Retrieve the stream. If resuming, pass last_event_id
stream = client.interactions.get(
id=interaction_id,
stream=True,
last_event_id=last_event_id
)
for event in stream:
# Log event updates and capture event_id if present
if event.event_id:
last_event_id = event.event_id
if event.event_type == "step.delta" and event.delta.type == "text":
print(event.delta.text, end="", flush=True)
if event.event_type == "interaction.completed":
return
except Exception as e:
print(f"\n[Connection lost: {e}. Reconnecting in 3s...]")
time.sleep(3)
stream_with_reconnect(interaction_id)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const interactionId = "YOUR_INTERACTION_ID";
async function streamWithReconnect(id) {
let lastEventId = undefined;
while (true) {
try {
const stream = await client.interactions.get(id, {
stream: true,
last_event_id: lastEventId
});
for await (const event of stream) {
const idVal = event.event_id || event.id;
if (idVal) {
lastEventId = idVal;
}
if (event.event_type === "step.delta" && event.delta?.type === "text") {
process.stdout.write(event.delta.text);
}
if (event.event_type === "interaction.completed") {
return;
}
}
} catch (error) {
console.log(`\n[Connection lost: ${error.message}. Reconnecting in 3s...]`);
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
}
await streamWithReconnect(interactionId);
REST
curl -N -X GET "https://generativelanguage.googleapis.com/v1beta/interactions/YOUR_INTERACTION_ID?stream=true&last_event_id=YOUR_LAST_EVENT_ID" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Api-Revision: 2026-05-20"
Multi-turn conversations
Subsequent interactions can chain to a background conversation using previous_interaction_id, subject to two constraints:
- Active executions are blocked: Chaining to an interaction with
in_progressstatus returns a400 Bad Request. Wait for the previous interaction to reachcompletedbefore starting the next one. - Environment parameter for Managed Agents: When chaining interactions for Managed Agents, requests must include both
previous_interaction_idandenvironment.
Python
import time
from google import genai
client = genai.Client()
agent_model = "antigravity-preview-05-2026"
# First interaction: provision sandbox environment and execute first instruction
interaction1 = client.interactions.create(
model=agent_model,
input="Create a folder named project/ and write hello.py inside.",
environment="remote",
background=True
)
# Wait for completion
while True:
check = client.interactions.get(id=interaction1.id)
if check.status != "in_progress":
break
time.sleep(2)
# Second interaction: chain using previous_interaction_id and environment
interaction2 = client.interactions.create(
model=agent_model,
input="List all files in the project/ directory.",
previous_interaction_id=interaction1.id,
environment="remote",
background=True
)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const agentModel = "antigravity-preview-05-2026";
// First interaction: provision sandbox environment and execute first instruction
const interaction1 = await client.interactions.create({
model: agentModel,
input: "Create a folder named project/ and write hello.py inside.",
environment: "remote",
background: true
});
// Wait for completion
while (true) {
const check = await client.interactions.get(interaction1.id);
if (check.status !== "in_progress") {
break;
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
// Second interaction: chain using previous_interaction_id and environment
const interaction2 = await client.interactions.create({
model: agentModel,
input: "List all files in the project/ directory.",
previous_interaction_id: interaction1.id,
environment: "remote",
background: true
});
REST
# Chain second interaction (make sure FIRST_INTERACTION_ID has status 'completed')
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
-d '{
"model": "antigravity-preview-05-2026",
"input": "List all files in the project/ directory.",
"previous_interaction_id": "FIRST_INTERACTION_ID",
"environment": "remote",
"background": true
}'
Cancellation and deletion
You can control running executions and manage storage with cancel and delete requests:
- Cancel (
POST /interactions/{id}/cancel): Stops the running task. The status transitions tocancelled. Clean-up actions on the server can cause a slight delay before the status updates in GET requests. - Delete (
DELETE /interactions/{id}): Removes the interaction records from the server. Subsequent GET requests return a404 Not Founderror.
Python
from google import genai
client = genai.Client()
# Cancel a running interaction
client.interactions.cancel(id="YOUR_INTERACTION_ID")
# Delete the interaction record entirely
client.interactions.delete(id="YOUR_INTERACTION_ID")
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
// Cancel a running interaction
await client.interactions.cancel("YOUR_INTERACTION_ID");
// Delete the interaction record entirely
await client.interactions.delete("YOUR_INTERACTION_ID");
REST
# Cancel the interaction
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions/YOUR_INTERACTION_ID/cancel" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Api-Revision: 2026-05-20"
# Delete the interaction
curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/interactions/YOUR_INTERACTION_ID" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Api-Revision: 2026-05-20"
Best practices
- Choose the right retrieval pattern: Poll for simple status checks; stream when you want live progress and to receive output incrementally.
- Make streaming resilient: Persist
last_event_idon each event so you can reconnect seamlessly after network drops. - Always wait before chaining: Never chain to an interaction that’s still
in_progress— you’ll get a400, so build your loop around reaching a terminal state. - Clean up after yourself: Cancel tasks you no longer need and delete interaction records to keep storage and costs in check.
Summary
Background execution turns the Gemini Interactions API into a true server-side task engine. You create an interaction asynchronously, get an ID back immediately, and then poll, stream, or reconnect to it as it completes. Combined with multi-turn chaining, cancellation, and deletion, it gives you everything you need to build robust, long-running agentic applications without fighting HTTP connection timeouts.
Further reading
- Read the Interactions API overview to understand session and state management.
- See the Streaming interactions guide for real-time event updates.
- Explore the Managed agents quickstart to build stateful multi-turn agents.