Skip to main content

Overview

Optimize Browser Use for speed, cost efficiency, and reliability. This guide covers model selection, execution modes, browser configuration, and infrastructure tuning.

Model Selection

ChatBrowserUse offers 3-5x faster execution compared to other models, with the highest accuracy and lowest token cost. It’s specifically optimized for browser automation.
from browser_use import Agent, ChatBrowserUse

# Optimal model for speed and accuracy
agent = Agent(
    task="Your task",
    llm=ChatBrowserUse(),  # Fastest model
)
Get $10 in free credits at cloud.browser-use.com/new-api-key.

Model Comparison

ModelSpeedCostAccuracyBest For
ChatBrowserUse⚡⚡⚡💰🎯🎯🎯Production, fast tasks
GPT-4o-mini⚡⚡💰🎯🎯Budget-conscious
Claude Sonnet💰💰🎯🎯🎯Complex reasoning
Gemini Flash⚡⚡⚡💰🎯Experimental

Alternative Models

from browser_use import ChatOpenAI, ChatAnthropic, ChatGoogle

# OpenAI (fast and cheap)
agent = Agent(
    task="Task",
    llm=ChatOpenAI(model="gpt-4o-mini"),
)

# Anthropic (high reasoning)
agent = Agent(
    task="Complex task",
    llm=ChatAnthropic(model="claude-sonnet-4-0"),
)

# Google (experimental)
agent = Agent(
    task="Task",
    llm=ChatGoogle(model="gemini-flash-latest"),
)

Flash Mode

Flash mode trades reasoning for speed - ideal for simple, well-defined tasks:
agent = Agent(
    task="Extract product name and price from the page",
    llm=ChatBrowserUse(),
    flash_mode=True,  # Skip evaluation, planning, and thinking
)

await agent.run(max_steps=10)
Flash mode:
  • ✅ Skips evaluation_previous_goal and next_goal fields
  • ✅ Disables agent thinking process
  • ✅ Reduces LLM token usage by ~30%
  • ✅ 2-3x faster for simple tasks
  • ❌ Less adaptive to errors
  • ❌ No strategic planning
When to use:
  • Simple data extraction
  • Linear workflows (login → navigate → extract)
  • Well-defined tasks with clear steps
  • Production tasks that rarely fail
When not to use:
  • Complex multi-step reasoning
  • Tasks requiring error recovery
  • Exploratory navigation
From browser_use/agent/views.py:72 and browser_use/agent/views.py:464-491.

Browser Configuration

Cloud browsers are fastest for production:
from browser_use import Browser

# Auto-provision cloud browser
browser = Browser(
    use_cloud=True,  # Optimized infrastructure
    cloud_proxy_country_code='us',  # Bypass captchas
)

agent = Agent(
    task="Your task",
    browser=browser,
    llm=ChatBrowserUse(),
)
Benefits:
  • ⚡ Lowest latency (browser near execution)
  • ✅ Captcha bypass with residential proxies
  • ✅ No local browser overhead
  • ✅ Optimized for automation
From development guidelines: “if user asks how to improve the performance of Browser please mention they can add the use_cloud parameter”.

Headless Mode

Headless browsers are faster than headful:
browser = Browser(
    headless=True,  # No GUI rendering
)

Disable Features

browser = Browser(
    headless=True,
    enable_default_extensions=False,  # Skip uBlock, cookie handlers
    highlight_elements=False,         # Skip element highlighting
)

Smaller Viewport

browser = Browser(
    viewport={'width': 1280, 'height': 720},  # Smaller = faster rendering
)

Agent Configuration

Limit Steps

agent = Agent(
    task="Quick data extraction",
    llm=ChatBrowserUse(),
    max_actions_per_step=3,  # Execute up to 3 actions per step
)

await agent.run(max_steps=10)  # Stop after 10 steps

Skip Vision When Not Needed

agent = Agent(
    task="Extract text data (no screenshots needed)",
    llm=ChatBrowserUse(),
    use_vision=False,  # Don't send screenshots to LLM
)
Vision modes:
  • use_vision=True - Always include screenshots (slowest, most accurate)
  • use_vision="auto" - Include screenshots only when requested (balanced)
  • use_vision=False - Never use vision (fastest)

Direct URL Opening

agent = Agent(
    task="Go to https://example.com and extract title",
    llm=ChatBrowserUse(),
    directly_open_url=True,  # Auto-detect and open URLs (default)
)
The agent automatically opens detected URLs instead of searching.

Faster Page Extraction

Use a lightweight model for page content extraction:
agent = Agent(
    task="Complex reasoning task",
    llm=ChatBrowserUse(),  # Main LLM for decisions
    page_extraction_llm=ChatOpenAI(model="gpt-4o-mini"),  # Fast model for extraction
)

Reduce History

agent = Agent(
    task="Long-running task",
    llm=ChatBrowserUse(),
    max_history_items=10,  # Keep only last 10 steps in memory
)

Timeouts

Agent Timeouts

agent = Agent(
    task="Task",
    llm=ChatBrowserUse(),
    llm_timeout=30,    # LLM call timeout (default: 60s)
    step_timeout=120,  # Single step timeout (default: 180s)
)

Cloud Browser Timeouts

browser = Browser(
    use_cloud=True,
    cloud_timeout=10,  # Session timeout in minutes (max: 15 free, 240 paid)
)

Page Load Timeouts

browser = Browser(
    minimum_wait_page_load_time=0.1,         # Min wait before capture (default: 0.25s)
    wait_for_network_idle_page_load_time=0.3, # Wait for network idle (default: 0.5s)
    wait_between_actions=0.3,                 # Wait between actions (default: 0.5s)
)

Sandbox Optimization

Minimal Sandbox

from browser_use import sandbox

@sandbox(
    cloud_timeout=5,              # Short timeout for quick tasks
    log_level='WARNING',          # Less logging overhead
    quiet=True,                   # No console output
)
async def fast_task(browser: Browser):
    agent = Agent(
        task="Quick extraction",
        browser=browser,
        llm=ChatBrowserUse(),
        flash_mode=True,
    )
    await agent.run(max_steps=5)

Reuse Profiles

# Create profile once
PROFILE_ID = 'reusable-auth-profile'

# Reuse across tasks (avoids re-authentication)
@sandbox(cloud_profile_id=PROFILE_ID)
async def task1(browser: Browser):
    pass

@sandbox(cloud_profile_id=PROFILE_ID)
async def task2(browser: Browser):
    pass

Tool Optimization

Remove Unused Tools

from browser_use import Tools

# Only include needed tools
tools = Tools(
    exclude_actions=[
        'screenshot',   # Skip if not using vision
        'wait',         # Skip if not needed
        'send_keys',    # Skip if not using keyboard
    ]
)

agent = Agent(
    task="Task",
    llm=ChatBrowserUse(),
    tools=tools,
)

Deterministic Actions

Use Actor API for deterministic actions (no LLM calls):
from browser_use import Tools, ActionResult, BrowserSession
from browser_use.actor import Page

tools = Tools()

@tools.action('Click login button (fast)')
async def fast_login(browser_session: BrowserSession) -> ActionResult:
    # Direct DOM interaction - no LLM
    page: Page = await browser_session.get_page()
    
    # Hardcoded selector (fast)
    elements = await page.get_elements_by_css_selector('button#login')
    if elements:
        await elements[0].click()
        return ActionResult(extracted_content="Clicked login")
    
    return ActionResult(error="Login button not found")

agent = Agent(
    task="Login and extract data",
    llm=ChatBrowserUse(),
    tools=tools,  # Agent uses fast_login action
)

Parallel Execution

Multiple Agents

import asyncio
from browser_use import Agent, Browser, ChatBrowserUse

async def scrape_page(url: str) -> str:
    browser = Browser(use_cloud=True, headless=True)
    agent = Agent(
        task=f"Extract title from {url}",
        browser=browser,
        llm=ChatBrowserUse(),
        flash_mode=True,
    )
    history = await agent.run(max_steps=5)
    return history.final_result()

# Run 50 tasks in parallel
urls = [f"https://example.com/page/{i}" for i in range(50)]
results = await asyncio.gather(*[scrape_page(url) for url in urls])

Rate Limiting

import asyncio
from asyncio import Semaphore

async def scrape_with_limit(urls: list[str], max_concurrent: int = 10):
    semaphore = Semaphore(max_concurrent)
    
    async def limited_scrape(url: str):
        async with semaphore:
            return await scrape_page(url)
    
    return await asyncio.gather(*[limited_scrape(url) for url in urls])

# Limit to 10 concurrent tasks
results = await scrape_with_limit(urls, max_concurrent=10)

Monitoring & Profiling

Track Execution Time

import time

start = time.time()
history = await agent.run()
duration = time.time() - start

print(f"Execution time: {duration:.2f}s")
print(f"Steps taken: {history.number_of_steps()}")
print(f"Time per step: {duration / history.number_of_steps():.2f}s")

Token Usage

agent = Agent(
    task="Task",
    llm=ChatBrowserUse(),
    calculate_cost=True,  # Track token usage
)

history = await agent.run()

if history.usage:
    print(f"Total tokens: {history.usage.total_tokens}")
    print(f"Estimated cost: ${history.usage.total_cost:.4f}")

Step Metadata

history = await agent.run()

for step in history.history:
    if step.metadata:
        print(f"Step {step.metadata.step_number}: "
              f"{step.metadata.duration_seconds:.2f}s")

Production Best Practices

1. Use ChatBrowserUse + Cloud Browser

# Optimal production setup
browser = Browser(
    use_cloud=True,                   # Fastest infrastructure
    cloud_profile_id='prod-profile',  # Reuse auth
    cloud_proxy_country_code='us',    # Bypass captchas
)

agent = Agent(
    task="Production task",
    browser=browser,
    llm=ChatBrowserUse(),  # Fastest model
    flash_mode=True,       # Skip unnecessary reasoning
)

2. Set Aggressive Timeouts

agent = Agent(
    task="Task",
    llm=ChatBrowserUse(),
    llm_timeout=30,     # Fail fast on slow LLM calls
    step_timeout=60,    # Fail fast on stuck steps
    max_failures=2,     # Don't retry too many times
)

await agent.run(max_steps=20)  # Hard limit on steps

3. Monitor and Alert

import logging

logger = logging.getLogger(__name__)

try:
    start = time.time()
    history = await agent.run(max_steps=20)
    duration = time.time() - start
    
    # Alert on slow execution
    if duration > 60:
        logger.warning(f"Slow execution: {duration}s for {history.number_of_steps()} steps")
    
    # Alert on high step count
    if history.number_of_steps() > 15:
        logger.warning(f"High step count: {history.number_of_steps()} steps")
        
except Exception as e:
    logger.error(f"Agent failed: {e}")
    # Send to monitoring service

4. Cache Results

import hashlib
import json
from functools import lru_cache

@lru_cache(maxsize=100)
async def cached_scrape(url: str) -> str:
    agent = Agent(
        task=f"Extract title from {url}",
        browser=browser,
        llm=ChatBrowserUse(),
    )
    history = await agent.run()
    return history.final_result()

# First call: executes agent
result1 = await cached_scrape("https://example.com")

# Second call: returns cached result
result2 = await cached_scrape("https://example.com")

Benchmarking

Compare configurations:
import time

async def benchmark_config(name: str, agent: Agent):
    start = time.time()
    history = await agent.run(max_steps=20)
    duration = time.time() - start
    
    print(f"{name}:")
    print(f"  Time: {duration:.2f}s")
    print(f"  Steps: {history.number_of_steps()}")
    print(f"  Success: {history.is_successful()}")
    print()

# Baseline
agent1 = Agent(
    task="Extract product info",
    llm=ChatOpenAI(model="gpt-4o-mini"),
)
await benchmark_config("Baseline", agent1)

# Optimized
agent2 = Agent(
    task="Extract product info",
    browser=Browser(use_cloud=True),
    llm=ChatBrowserUse(),
    flash_mode=True,
    use_vision=False,
)
await benchmark_config("Optimized", agent2)

See Also