← Blog

BLOG

Playwright connectOverCDP Documentation: Connect to Remote Chrome

Playwright connectOverCDP documentation: connect to remote Chrome instances via CDP. Learn how to attach to hosted browsers for reliable automation.

September 7, 202610 min readRemote Browser

# Playwright connectOverCDP Documentation: Connecting to Remote Chrome

Playwright's connectOverCDP method is the official way to attach your automation scripts to an already-running Chrome or Chromium instance. Instead of launching a new browser process, you connect to an existing one over the Chrome DevTools Protocol (CDP). This is essential for AI agents, long-running automation, and any workflow that needs a persistent browser session. This guide serves as practical Playwright connectOverCDP documentation, covering how it works, when to use it, and how to scale it beyond a single local machine.

What is Playwright connectOverCDP?

The browserType.connectOverCDP() method in Playwright allows you to connect to a browser that is already running with the --remote-debugging-port flag. It returns a Browser object that you can control just like a locally launched one, but it operates on the remote instance.

import { chromium } from 'playwright';

// Connect to an existing Chrome instance
const browser = await chromium.connectOverCDP('http://localhost:9222');
const defaultContext = browser.contexts()[0];
const page = defaultContext.pages()[0];

// Use the page as usual
await page.goto('https://example.com');
console.log(await page.title());

await browser.close();

This is fundamentally different from chromium.launch(). With launch(), Playwright creates a fresh browser process with a clean profile. With connectOverCDP(), you attach to an existing process, preserving its state, cookies, and open tabs.

Why Use connectOverCDP Instead of Launch?

The core use case for connectOverCDP is controlling a browser that you do not own the lifecycle of. Consider these scenarios:

  1. Debugging a live session: You have a browser open with a user logged in, and you want to run a script against that exact state.
  2. Persistent sessions: You need a browser that stays alive across multiple script executions or cloud workers. A launch() call creates a browser, runs a script, and typically closes it. connectOverCDP lets you connect to a browser that remains running.
  3. AI agent control: An AI agent needs to perform a task, pause, and resume later without losing its place. The browser session is the agent's "memory" of the page state.

The trade-off is control. When you launch() a browser, Playwright manages the process lifecycle, ensuring a clean state. When you connectOverCDP(), you inherit the state of the existing browser. This is powerful but requires careful session management.

The Problem: Local connectOverCDP Doesn't Scale

While connectOverCDP solves the persistence problem on a single machine, it introduces a new one: infrastructure. To use it, you must:

  • Run a Chrome instance with --remote-debugging-port=9222.
  • Ensure that port is accessible to your script.
  • Keep that machine running 24/7.
  • Manage the browser's resource usage (CPU, memory).
  • Handle crashes and restarts.

This is manageable for one developer on a laptop, but it breaks down in production. AI agents often run on serverless functions or ephemeral cloud workers. These environments do not allow you to keep a browser process alive between invocations. If your agent runs on a worker that spins down after each task, a local connectOverCDP connection is useless—the browser dies with the worker.

The Production Alternative: Hosted Chromium via CDP

This is where a hosted browser runtime becomes necessary. Instead of managing your own Chrome instance, you connect to a remote Chromium browser that runs in the cloud. The connection mechanism is identical—your Playwright script uses connectOverCDP—but the browser lives in a data center, not on your laptop.

Remote Browser provides exactly this. It runs hosted Chromium sessions that you can connect to using Playwright's connectOverCDP method. Your script connects to a URL like wss://remote-browser.dev/... instead of http://localhost:9222.

FeatureLocal Chrome (Manual)Remote Browser (Hosted)
Session PersistenceDies with the processPersists across connections
InfrastructureYou manage the VM/processFully managed
ScalabilityLimited to one machineMultiple concurrent sessions
Live DebuggingManual (DevTools)Built-in live viewer
Profile ManagementManual file systemAPI-driven persistent profiles
Proxy SupportManual configurationConfigurable browser settings

How to Connect to Remote Browser with connectOverCDP

Connecting to a Remote Browser session is straightforward. The API is the same as connecting to a local instance; only the endpoint changes.

Step 1: Create a Browser Session

First, you need a running browser session. With Remote Browser, you create one via the API or dashboard. The API returns a cdpEndpoint—a WebSocket URL you will use to connect.

Step 2: Connect with Playwright

Use the cdpEndpoint in your connectOverCDP call.

import { chromium } from 'playwright';

// The CDP endpoint from your Remote Browser session
const cdpEndpoint = 'wss://remote-browser.dev/your-session-id';

// Connect to the hosted browser
const browser = await chromium.connectOverCDP(cdpEndpoint);

// Get the default context and page
const context = browser.contexts()[0];
const page = context.pages()[0];

// Perform your automation
await page.goto('https://news.ycombinator.com');
const title = await page.title();
console.log(`Page title: ${title}`);

// Do NOT close the browser if you want to keep the session alive.
// Instead, just disconnect.
await browser.close();

Key Difference: When you call browser.close() on a local browser, it kills the process. When you call it on a Remote Browser session, it only disconnects your script. The browser session continues running in the cloud. This is the critical feature for keeping sessions alive across multiple cloud workers.

Keeping Browser Sessions Alive Across Cloud Workers

The related search query "how to keep browser sessions alive across multiple cloud workers?" points to a common pain point. Serverless functions are stateless. You cannot guarantee that two invocations will run on the same machine.

With a hosted browser, the state lives in the cloud, not on the worker. Here is the pattern:

  1. Worker A (e.g., a webhook handler) receives a task. It calls the Remote Browser API to create a session and gets a cdpEndpoint.
  2. Worker A connects via connectOverCDP, navigates to a login page, and fills in credentials. It then disconnects. The browser session remains logged in.
  3. Worker B (e.g., a cron job) picks up the next task. It uses the same cdpEndpoint to connect.
  4. Worker B finds the browser still logged in and continues from where Worker A left off.

This pattern turns a stateless worker into a stateful agent. The browser is the state.

Playwright connectOverCDP: Chromium Only

A common point of confusion in Playwright connectOverCDP documentation is browser support. The connectOverCDP method is only for Chromium-based browsers. It does not work with Firefox or WebKit.

The Playwright documentation is explicit: chromium.connectOverCDP() is the only implementation. If you need to connect to Firefox, you must use the WebDriver BiDi protocol, which is a different connection method.

For production workloads, Chromium is the standard choice. It has the broadest support for automation features and is the primary target for AI agent frameworks.

Scaling Playwright Browser Workloads Reliably

Scaling browser automation is hard. The related query "how to scale playwright browser workloads reliably?" highlights the operational burden. When you run Playwright locally, you are limited by your machine's resources. Each browser instance consumes significant CPU and memory.

Resource Management

A single Chromium instance can easily consume 500MB+ of RAM, especially with complex pages. Running 10 concurrent sessions on a laptop is impractical. A hosted service abstracts this away. You request a session, use it, and release it. The provider handles the underlying resource allocation.

Session Isolation

When running multiple automation tasks, isolation is critical. A failing script on one session should not affect another. Remote Browser provides session isolation, ensuring that each connectOverCDP connection targets a dedicated browser instance. This prevents cross-contamination of cookies, cache, and other state.

The --sandbox Default Issue

A frequent issue when running Playwright in containers is the Chromium sandbox. The related keyword %site.playwright.dev docs api browser-type chromiumsandbox defaults false points to a specific documentation page about the chromiumSandbox option.

In Playwright, the chromiumSandbox option defaults to false when running as root (common in Docker containers). This is a security risk. The sandbox is a critical security boundary that prevents a compromised renderer process from accessing the system.

When you use a hosted browser service, this concern is handled by the provider. The browsers run in a secure, isolated environment where the sandbox configuration is managed correctly. You do not need to disable the sandbox or worry about container-specific security issues.

Selenium vs. Playwright for Remote Browsers

While this guide focuses on Playwright, the same CDP connection pattern applies to Selenium. Selenium 4 supports CDP directly, allowing you to connect to the same remote browser endpoints.

FeaturePlaywright connectOverCDPSelenium CDP
ConnectionDirect WebSocket connectionVia Selenium's ChromiumDriver
API StyleAsync/Await nativeCallback/Promise based
Browser SupportChromium onlyChromium only (for CDP)
EcosystemModern, fast-growingMature, large community
Language SupportJS/TS, Python, Java, .NETJava, Python, JS, C#, Ruby

If you are starting a new project, Playwright's API is generally considered more ergonomic for complex automation. If you have a large existing Selenium suite, you can still use a hosted browser by connecting via CDP.

Giving Your AI Agent Browser Access in Production

The question "how can i give my ai agent browser access in production?" is about more than just connecting to a browser. It is about creating a reliable, observable, and secure environment for the agent to operate in.

An AI agent needs more than a page.goto() function. It needs to:

  • Persist state across multiple steps and retries.
  • Handle authentication without re-entering credentials every time.
  • Be observable so a human can intervene if the agent gets stuck.
  • Run concurrently to handle multiple tasks.

A hosted browser runtime provides these features. The agent connects via connectOverCDP, performs its task, and disconnects. The session remains available for the next step, and a live viewer allows developers to watch the agent's progress in real-time.

What is a Browser Agent?

The term "browser agent" is often used loosely. In the context of this documentation, a browser agent is any AI model (like GPT-4 or Claude) that uses a browser as a tool to interact with the web. The agent receives a task, breaks it down into steps, and uses browser automation to execute those steps.

The agent is not the browser. The agent is the "brain" that decides what to do. The browser is the "hands" that execute the actions. The connectOverCDP method is the "nervous system" that connects the brain to the hands.

For an agent to work reliably, the hands (browser) must be stable. A local browser that crashes or loses state will cause the agent to fail. A hosted browser provides the stability required for production AI agents.

Practical Implementation: A Persistent Login Session

Let's walk through a concrete example of using connectOverCDP to maintain a login session across two separate script executions.

Script 1: Login and Save State

import { chromium } from 'playwright';

async function loginAndDisconnect() {
  const cdpEndpoint = 'wss://remote-browser.dev/session-123';
  const browser = await chromium.connectOverCDP(cdpEndpoint);
  const context = browser.contexts()[0];
  const page = context.pages()[0];

  await page.goto('https://app.example.com/login');
  await page.fill('#username', 'myuser');
  await page.fill('#password', 'mypassword');
  await page.click('#submit');
  await page.waitForURL('https://app.example.com/dashboard');

  console.log('Logged in. Disconnecting...');
  // This disconnects the script but keeps the browser session alive.
  await browser.close();
}

loginAndDisconnect();

Script 2: Use the Authenticated Session

import { chromium } from 'playwright';

async function useAuthenticatedSession() {
  const cdpEndpoint = 'wss://remote-browser.dev/session-123';
  const browser = await chromium.connectOverCDP(cdpEndpoint);
  const context = browser.contexts()[0];
  const page = context.pages()[0];

  // We are still logged in!
  await page.goto('https://app.example.com/settings');
  console.log(await page.title());

  await browser.close();
}

useAuthenticatedSession();

This pattern is the foundation for building robust AI agents that can operate over long time horizons without repeating authentication steps.

Conclusion

Playwright's connectOverCDP is a powerful method for controlling existing browser instances. It is the correct tool when you need persistent sessions, live debugging, or stateful automation. However, using it effectively in production requires solving the infrastructure problem of keeping a browser alive and accessible.

A hosted browser runtime like Remote Browser solves this by providing always-on Chromium sessions that you can connect to using the standard connectOverCDP API. This allows you to focus on your automation logic and AI agent behavior, rather than managing browser infrastructure.

For more details on the API, check the official documentation. To understand the cost structure, visit the pricing page. If you are building an AI agent, read about the runtime requirements for AI agents. For a broader overview of hosted browsers, see our guide on remote web browsers or the remote control browser concept.

For the authoritative reference on the connectOverCDP method, refer to the official Playwright BrowserType documentation.