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 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 
⌘I