Skip to main content
Stagehand performance depends on several factors: DOM processing speed, LLM inference time, browser operations, and network latency. This guide provides proven strategies to maximize automation speed.

Quick Performance Wins

1. Plan Ahead with Observe

Use a single observe() call to plan multiple actions, then execute them efficiently:
// Instead of sequential operations with multiple LLM calls
await stagehand.act("Fill name field");        // LLM call #1
await stagehand.act("Fill email field");       // LLM call #2
await stagehand.act("Select country dropdown"); // LLM call #3

// Use single observe to plan all form fields - one LLM call
const formFields = await stagehand.observe("Find all form fields to fill");

// Execute all actions without LLM inference
for (const field of formFields) {
  await stagehand.act(field); // No LLM calls!
}
Performance Tip: Acting on observe results avoids LLM inference entirely. This approach is 2-3x faster than direct act() calls and is the recommended pattern for multi-step workflows.

Caching Guide

Learn advanced caching patterns and cache invalidation strategies

2. Optimize DOM Processing

Reduce DOM complexity before Stagehand processes the page:
// Remove heavy elements that slow down processing
await page.evaluate(() => {
  // Remove video elements
  document.querySelectorAll('video, iframe').forEach(el => el.remove());
  
  // Hide complex animations
  document.querySelectorAll('[style*="animation"]').forEach(el => {
    (el as HTMLElement).style.animation = 'none';
  });
});

// Then perform Stagehand operations
await stagehand.act("Click the submit button");

3. Set Appropriate Timeouts

Use shorter timeouts for simple operations and longer ones for complex page loads:
// Simple actions - reduce action timeout
await stagehand.act("Click the login button", {
  timeout: 5000  // Default is 30000ms, reduce for simple clicks
});

// Complex page loads - optimize navigation
const page = stagehand.context.pages()[0];
await page.goto("https://heavy-spa.com", {
  waitUntil: "domcontentloaded", // Don't wait for all resources
  timeout: 15000 // Shorter than default 30s
});

Performance Monitoring and Benchmarking

Track performance metrics and measure optimization impact:

Performance Tracking

class PerformanceTracker {
  private speedMetrics: Map<string, number[]> = new Map();

  async timedAct(page: Page, prompt: string): Promise<ActResult> {
    const start = Date.now();
    const result = await stagehand.act(prompt);
    const duration = Date.now() - start;
    
    if (!this.speedMetrics.has(prompt)) {
      this.speedMetrics.set(prompt, []);
    }
    this.speedMetrics.get(prompt)!.push(duration);
    
    console.log(`Action "${prompt}" took ${duration}ms`);
    return result;
  }

  getAverageTime(prompt: string): number {
    const times = this.speedMetrics.get(prompt) || [];
    return times.reduce((a, b) => a + b, 0) / times.length;
  }
}
Example Output:
Action "Fill form" took 1000ms
Action "Click submit" took 2000ms
Action "Confirm submission" took 5000ms

Before vs After Benchmarking

// Before optimization
console.time("workflow");
await stagehand.act("Fill form");
await stagehand.act("Click submit");
await stagehand.act("Confirm submission");
console.timeEnd("workflow"); // 8000ms

// After optimization with observe planning
console.time("workflow-optimized");
const workflowActions = await stagehand.observe("Find form, submit, and confirm elements");

// Execute actions sequentially to avoid conflicts
for (const action of workflowActions) {
  await stagehand.act(action);
}
console.timeEnd("workflow-optimized"); // 500ms
Example Output:
Workflow took 8000ms
Optimized workflow took 500ms

Observability & Metrics

Set up comprehensive performance monitoring

Caching Strategies

Advanced caching patterns for maximum performance

Cost Optimization

Balance speed improvements with cost considerations

Browser Configuration

Optimize Browserbase settings for speed

Model Selection

Choose the right model for speed vs accuracy