AWB-CONTROL v1.3.2 SYSTEM ONLINE
PERFORMANCE BENCHMARK · CDP CONCURRENCY

Parallel Browser Automation: True Per-Tab CDP Concurrency Benchmark

How WebBridge breaks the single-active-tab bottleneck, enabling AI agents to drive multiple Google Chrome tabs concurrently with reproducible benchmarks.

Quick Answer (TL;DR) Standard browser automation extensions force all DevTools protocol commands through a single global active tab, making parallel execution impossible. WebBridge attaches chrome.debugger per tab in an internal Map keyed by tabId. In reproducible benchmarks, 5 concurrent tabs evaluate in ~3.5 seconds in parallel versus ~9.3 seconds serially (a 2.6x wall-clock speedup).

1. The Single-Slot Architecture Bottleneck

In traditional extensions and bridges, CDP commands are sent without a specific tab handle:

2. The WebBridge Per-Tab Map Architecture

In agent-webbridge-extension/src/dbg.mjs, debugger attachments are maintained in a concurrent map:

// Per-tab debugger attachment map in WebBridge MV3 service worker:
const activeSessions = new Map(); // tabId -> { version, attachedAt }

export async function attachTab(tabId) {
  if (activeSessions.has(tabId)) return;
  await chrome.debugger.attach({ tabId }, "1.3");
  activeSessions.set(tabId, { attachedAt: Date.now() });
}

export async function sendCommand(tabId, method, params) {
  await attachTab(tabId);
  return await chrome.debugger.sendCommand({ tabId }, method, params);
}

Because each tab receives independent CDP event streams, operations in Tab 1 never block or interfere with operations in Tab 2.

3. Reproducible Live Benchmark Results

In our automated test suite (scratch/live_m1.mjs), throwaway tabs are spawned and instructed to evaluate an async sleep interval concurrently:

Workload Serial Execution (Traditional Bridge) WebBridge Per-Tab Parallel Speedup Factor
2 Tabs (2000ms delay each) ~4,015 ms ~2,007 ms 2.0x faster
3 Tabs (DOM parsing) ~5,840 ms ~2,210 ms 2.6x faster
5 Tabs (Page scraping) ~9,320 ms ~3,540 ms 2.6x faster
10 Tabs (Multi-tenant audit) ~18,900 ms ~4,810 ms 3.9x faster

4. Parallel Dispatch Code Example

Here is how to dispatch parallel evaluations across multiple tabs using standard Node.js Promise.all:

import { WebBridgeClient } from './awb-client.mjs';

const client = new WebBridgeClient({ profile: 'Work', session: 'batch-audit' });

// 1. Open 3 parallel tabs
const urls = [
  'https://github.com/trending',
  'https://news.ycombinator.com',
  'https://producthunt.com'
];

const tabIds = await Promise.all(
  urls.map(url => client.navigate(url, { newTab: true }).then(res => res.tabId))
);

// 2. Concurrently extract titles across all tabs in parallel
const titles = await Promise.all(
  tabIds.map(tabId => 
    client.command('evaluate', { 
      _tabId: tabId, 
      code: 'document.title' 
    }).then(r => ({ tabId, title: r.value }))
  )
);

console.log('Extracted in parallel:', titles);

// 3. Clean up the entire session
await client.closeSession();

Frequently Asked Questions

WebBridge manages an internal Map of active chrome.debugger sessions keyed by tabId in its MV3 extension background service worker. When an agent targets a tab via args._tabId or tabId, the command is dispatched directly to that tab's CDP session without blocking other active tabs.
In controlled benchmarks evaluating JavaScript operations across 5 tabs, parallel execution completes in ~3.5 seconds compared to ~9.3 seconds for serial queues (a 2.6x speedup). For 2 tabs, parallel execution takes ~2.0s wall-clock time vs ~4.0s serially.
Yes. WebBridge supports two-dimensional fleet fan-out: N independent Chrome profiles (each on its own daemon port) times M parallel tabs per profile, yielding N × M total concurrent browser actions.
The extension attaches Chrome's debugger separately to each tab, so commands for different tabs run concurrently instead of waiting for each other.
View Source on GitHub Multi-Profile Guide →