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 page.act("Fill name field");        // LLM call #1
await page.act("Fill email field");       // LLM call #2
await page.act("Select country dropdown"); // LLM call #3

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

// Execute all actions without LLM inference
for (const field of formFields) {
  await page.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 page.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 page.act({ 
  instruction: "Click the login button",
  actTimeout: 5000  // Default is 30000ms, reduce for simple clicks
});

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

Advanced Performance Strategies

Smart Model Selection

Use faster models for simple tasks, premium models only when needed:
class SpeedOptimizedStagehand {
  private fastModel: Stagehand;
  private premiumModel: Stagehand;

  async smartAct(page: Page, prompt: string, complexity: 'simple' | 'complex') {
    const model = complexity === 'simple' ? this.fastModel : this.premiumModel;
    return await model.page.act(prompt);
  }
}

// Use fast model for simple clicks/forms
await stagehand.smartAct(page, "Click submit", 'simple');

// Use premium model for complex reasoning
await stagehand.smartAct(page, "Find the cheapest flight option", 'complex');

Model Configuration

Compare model performance and costs

Page Load Optimization

Skip unnecessary resources during page loads:
// Block heavy resources globally
await context.route('**/*', (route) => {
  const resourceType = route.request().resourceType();
  if (['image', 'font', 'media'].includes(resourceType)) {
    route.abort();
  } else {
    route.continue();
  }
});

// Use faster navigation
await page.goto(url, { 
  waitUntil: 'domcontentloaded',  // Don't wait for images/fonts
  timeout: 10000 
});

Cost Optimization

Balance speed with cost considerations

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 page.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 page.act("Fill form");
await page.act("Click submit");
await page.act("Confirm submission");
console.timeEnd("workflow"); // 8000ms

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

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