Skip to main content
Deterministic rerun lets you run a browser task once with a full agent, then re-execute the same task instantly using a cached script — no LLM, up to 99% cheaper.

Quick start

Use {{double brackets}} around values that can change between runs. The first call runs the full agent. Every subsequent call with the same template uses the cached script.
from browser_use_sdk.v3 import AsyncBrowserUse

client = AsyncBrowserUse()
workspace = await client.workspaces.create(name="my-scraper")

# First call — agent explores, creates script (~$0.10, ~60s)
result = await client.run(
    "Get the top {{5}} stories from https://news.ycombinator.com as JSON",
    workspace_id=str(workspace.id),
)

# Second call — cached script, different param ($0 LLM, ~5s)
result2 = await client.run(
    "Get the top {{10}} stories from https://news.ycombinator.com as JSON",
    workspace_id=str(workspace.id),
)

How it works

1

You send a task with {{brackets}}

The brackets mark which parts are parameters:
"Get prices from {{example.com}} for {{electronics}}"
  • {{example.com}} → parameter 1
  • {{electronics}} → parameter 2
The system strips the values to create a template: "Get prices from {{}} for {{}}".
2

System hashes the template

Template "Get prices from {{}} for {{}}" is hashed to a unique ID like a7f3b2c1. The system checks the workspace for scripts/a7f3b2c1.py.
3

Cache miss → agent creates script

If no script exists, the full agent runs your task. After completing it, the agent saves a standalone Python script that reproduces the result deterministically — no AI needed.
4

Cache hit → script executes directly

If the script exists, it runs directly with the new parameter values. No agent, no LLM. Just the script in a sandbox with browser and proxy.

Auto-detection

Caching activates automatically when both conditions are met:
  • The task contains {{ and }}
  • A workspace_id is provided
No extra flags needed. You can override with cache_script:
ValueBehavior
None (default)Auto-detect from {{brackets}} + workspace
TrueForce-enable, even without brackets
FalseForce-disable, even if brackets are present

Examples

Parameterized scraping

Run once, then loop over different keywords at $0 LLM each:
# Agent figures out how to scrape intro.co on first call
result = await client.run(
    "Go to {{https://intro.co/marketplace}} and get all {{logistics}} experts as JSON",
    workspace_id=str(workspace.id),
)

# Instant reruns with different keywords
for keyword in ["CEO", "marketing", "finance", "e-commerce"]:
    result = await client.run(
        f"Go to {{{{https://intro.co/marketplace}}}} and get all {{{{{keyword}}}}} experts as JSON",
        workspace_id=str(workspace.id),
    )
    print(f"{keyword}: {len(result.output)} experts, LLM cost: ${result.llm_cost_usd}")

No parameters — cache the exact task

Append empty brackets {{}} to signal “cache this exact task”:
result = await client.run(
    "Get the current Bitcoin price from coinmarketcap.com {{}}",
    workspace_id=str(workspace.id),
)

# Same task again — cached
result2 = await client.run(
    "Get the current Bitcoin price from coinmarketcap.com {{}}",
    workspace_id=str(workspace.id),
)

Multiple parameters

result = await client.run(
    "Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{Germany,France,Japan}}",
    workspace_id=str(workspace.id),
)

# Different countries — cached
result2 = await client.run(
    "Go to https://help.netflix.com/en/node/24926/ax and get subscription prices for {{US,UK,Brazil}}",
    workspace_id=str(workspace.id),
)

Force enable / disable

# Force-enable without brackets
result = await client.run(
    "Get the top stories from Hacker News",
    workspace_id=str(workspace.id),
    cache_script=True,
)

# Force-disable even with brackets
result = await client.run(
    "Explain what {{templates}} means in Jinja",
    workspace_id=str(workspace.id),
    cache_script=False,
)

Inspecting cached scripts

You can download and inspect the scripts the agent created:
files = await client.workspaces.files(workspace.id, prefix="scripts/")
for f in files.files:
    print(f"{f.path}  ({f.size} bytes)")

# Download a script to inspect it
await client.workspaces.download(workspace.id, "scripts/a7f3b2c1.py", to="./my_script.py")

Cost comparison

LLM costBrowser + proxyTime
First call (agent)~$0.05–1.00Yes~30–120s
Cached calls$0Yes~3–10s
The browser and proxy still run for cached calls (the script may need them), so there is a small infrastructure cost per execution. LLM cost drops to zero.