← Blog

BLOG

Playwright CDP: How to Connect Playwright to Remote Chrome

Playwright CDP explained: connect Playwright to a remote Chrome browser via the DevTools Protocol for AI agents and automation.

August 25, 20269 min readRemote Browser

# Playwright CDP: How to Connect Playwright to Remote Chrome

Playwright CDP is the bridge between your automation code and a browser you don't control locally. When you connect Playwright to a remote Chrome instance over the Chrome DevTools Protocol (CDP), you get the same API you already know, but the browser runs in the cloud. This matters for AI agents that need persistent sessions, for teams that want to avoid managing browser infrastructure, and for anyone who has hit the limits of running Chromium on a single machine.

In this guide, you'll learn how Playwright's CDP connection works, when to use it over a standard Playwright launch, and how to wire it to a hosted browser runtime like Remote Browser.

What Is Playwright CDP?

CDP is the protocol that Chrome exposes for debugging and automation. Playwright normally talks to browsers through its own driver, but it can also connect to an existing Chrome instance over CDP. This is useful when:

  • You have a browser already running in the cloud and want to attach to it.
  • You need to debug a session that's live in production.
  • You want to reuse a persistent browser profile across multiple script runs.
  • You're building an AI agent that needs to keep a browser session alive between tasks.

The key method is chromium.connectOverCDP(). It takes a WebSocket endpoint URL and returns a Browser object that behaves like the one you get from chromium.launch(). The difference is that the browser process is not managed by your Playwright script—it's managed elsewhere.

import { chromium } from 'playwright';

// Connect to a remote Chrome instance via CDP
const browser = await chromium.connectOverCDP('wss://remote-browser.dev/cdp/your-session-id');

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

// Navigate and interact
await page.goto('https://example.com');
await page.click('button#submit');

// The session stays alive after your script exits
await browser.close();

That's the core pattern. You connect, you drive the page, and you disconnect. The browser itself keeps running.

Why Connect Playwright to a Remote Browser?

Running Playwright locally works for small test suites. But when you move to production workloads—AI agents, scraping pipelines, or 24/7 monitoring—local browsers become a bottleneck.

1. Session Persistence Across Workers

A common problem: you have a cloud worker that starts a Playwright script, opens a browser, does some work, and exits. The next worker starts fresh. Any cookies, local storage, or login state is gone.

With a remote browser over CDP, the browser session lives independently of your worker. You can connect from one worker, do part of a task, disconnect, and reconnect from another worker later. The session state is preserved because the browser process never stopped.

This is how you keep browser sessions alive across multiple cloud workers. Instead of serializing cookies and replaying them, you keep the actual browser running and attach to it over CDP.

2. No Local Browser Infrastructure

When you use chromium.launch(), you're responsible for installing Chromium, keeping it updated, managing dependencies, and ensuring the environment has enough memory and CPU. On a serverless platform, this is often impossible—you can't run a full browser in a Lambda function's execution environment.

A remote browser API removes that burden. The browser runs on infrastructure designed for it. Your code just connects over CDP.

3. Live Debugging and Observability

When a Playwright script fails locally, you can inspect the browser window. In the cloud, you can't. But with a remote browser that exposes a live viewer, you can watch the session in real time, take screenshots, and even take over the browser manually if needed.

This is critical for AI agents that make mistakes. You need to see what the agent saw, not just read a log.

Playwright CDP vs. Standard Playwright Launch

Here's a comparison of the two approaches:

Aspectchromium.launch()chromium.connectOverCDP()
Browser locationLocal machineRemote server
Session persistenceLost when script exitsSurvives script exit
Infrastructure managementYou manage itProvider manages it
ScalingLimited by local resourcesScales with provider
DebuggingLocal DevToolsRemote live viewer
Use caseDevelopment, small testsProduction, AI agents, persistent sessions

The trade-off is latency. Every CDP command travels over the network. For most automation tasks, this is negligible. For high-frequency interactions, it can add up. If you're doing thousands of actions per second, a local browser will be faster. But for AI agents that think between actions, the latency is irrelevant.

How to Connect Playwright to a Remote Browser

Remote Browser exposes a CDP endpoint for each browser session. You get a WebSocket URL that looks like wss://remote-browser.dev/cdp/<session-id>. Pass that to connectOverCDP() and you're in.

Step 1: Create a Browser Session

Before you can connect, you need a running browser. With Remote Browser, you create a session via the API. The session starts a Chromium instance in the cloud, ready to accept CDP connections.

Step 2: Connect Over CDP

Once the session is live, you get the WebSocket URL. Use it in your Playwright script:

import { chromium } from 'playwright';

const cdpUrl = process.env.REMOTE_BROWSER_CDP_URL;
const browser = await chromium.connectOverCDP(cdpUrl);

// Work with the existing context
const context = browser.contexts()[0];
const page = await context.newPage();
await page.goto('https://news.ycombinator.com');

// Do your work...

Step 3: Disconnect Without Killing the Browser

The important part: browser.close() in a CDP connection does not kill the remote browser. It only disconnects your client. The browser session stays alive, keeping its state.

This is the key to persistent sessions. You can run a script, disconnect, and reconnect later. The cookies, the DOM, the scroll position—all preserved.

Playwright CDP for AI Agents

AI agents are the biggest driver of remote browser adoption. An agent needs to browse the web, fill forms, click buttons, and extract information. It also needs to recover from errors and continue where it left off.

With Playwright CDP, an agent can:

  • Maintain context across turns. The agent connects to the same browser session for each step, so it doesn't lose track of what it's done.
  • Use a human-in-the-loop workflow. A human can watch the live viewer and intervene if the agent goes off track.
  • Run in production without a local browser. The agent runs on a server, connecting to a remote browser over CDP.

Here's a practical pattern for an AI agent loop:

import { chromium } from 'playwright';

async function agentStep(cdpUrl: string, instruction: string) {
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = browser.contexts()[0];
  const page = context.pages()[0] || await context.newPage();

  // Agent logic: parse instruction, decide action, execute
  // This is where you'd call your LLM and map its output to Playwright actions

  await browser.close(); // Disconnect, don't kill
}

Each step connects, acts, and disconnects. The browser stays alive between steps.

Browser-as-a-Service vs. Self-Hosted Playwright Infrastructure

You have two options for running Playwright at scale: build your own infrastructure or use a browser-as-a-service provider.

Self-Hosted Playwright Infrastructure

You run a fleet of Chrome instances, expose CDP endpoints, and manage load balancing, scaling, and session lifecycle.

Pros:

  • Full control over the environment.
  • No per-hour costs beyond your own infrastructure.
  • Can customize Chromium flags and build.

Cons:

  • Significant engineering time to build and maintain.
  • You handle security, updates, and scaling.
  • Hard to debug issues in production without building your own tooling.

Browser-as-a-Service (Remote Browser)

You call an API to create a browser session, get a CDP URL, and connect.

Pros:

  • No infrastructure to manage.
  • Built-in live viewer, session persistence, and proxy support.
  • Scales on demand.

Cons:

  • Per-hour cost.
  • Less control over the underlying environment.
  • Network latency for CDP commands.

For most teams, the trade-off favors browser-as-a-service. The engineering time to build and maintain a browser fleet is substantial. Unless you have a dedicated infrastructure team, the cost of self-hosting exceeds the per-hour fees.

Common Playwright CDP Pitfalls

1. Multiple Clients on One Session

CDP allows multiple clients to connect to the same browser. But Playwright's connectOverCDP() expects to manage the browser. If another client interferes, you can get unexpected behavior.

Fix: Use one Playwright client per session. If you need multiple workers, create multiple sessions.

2. Context and Page Management

When you connect over CDP, you don't create a new browser context. You attach to the existing one. If the session was created with a default context, use browser.contexts()[0]. Don't call browser.newContext() unless you want a fresh, isolated context.

3. WebSocket Disconnects

Network issues can drop the CDP connection. Playwright will throw an error. Your code should handle reconnection gracefully.

async function connectWithRetry(cdpUrl: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await chromium.connectOverCDP(cdpUrl);
    } catch (e) {
      if (i === retries - 1) throw e;
      await new Promise(r => setTimeout(r, 1000 * (i + 1)));
    }
  }
}

4. Session Timeout

Remote browser providers may terminate idle sessions. Check your provider's session timeout policy. If you need long-running sessions, make sure your provider supports them or implement a keep-alive mechanism.

Production Criteria for Playwright CDP

When you move from a local Playwright script to a remote CDP connection, evaluate these criteria:

  • Session persistence: Can you disconnect and reconnect without losing state?
  • Observability: Can you watch the browser live and take screenshots?
  • Proxy support: Can you route traffic through different IPs if needed?
  • Concurrency limits: How many parallel sessions can you run?
  • Cost model: Are you paying per hour, per session, or per action?

Remote Browser addresses these with hosted Chromium sessions, a live viewer, configurable browser settings, and session isolation. For current pricing and limits, check the pricing page.

Getting Started with Playwright CDP on Remote Browser

The setup is straightforward:

  1. Create an account and get an API key.
  2. Create a browser session via the API.
  3. Get the CDP WebSocket URL.
  4. Connect with chromium.connectOverCDP().

Here's a minimal example:

import { chromium } from 'playwright';

// Fetch a session from Remote Browser API
const response = await fetch('https://remote-browser.dev/api/sessions', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.REMOTE_BROWSER_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ browser: 'chromium' })
});

const session = await response.json();
const browser = await chromium.connectOverCDP(session.cdpUrl);

const page = await browser.contexts()[0].newPage();
await page.goto('https://example.com');
console.log(await page.title());

await browser.close();

Conclusion

Playwright CDP is the standard way to connect your automation code to a browser you don't control locally. It enables persistent sessions, remote debugging, and production-scale browser automation without managing infrastructure.

For AI agents, this is especially important. An agent needs a browser that stays alive between steps, that a human can observe, and that runs reliably in production. Playwright CDP to a hosted browser provides exactly that.

If you're building an AI agent or scaling your Playwright workflows, start with a remote browser session. Connect over CDP, keep the session alive, and focus on your application logic instead of browser infrastructure.

For more context on how remote browsers fit into your stack, read about remote browsers for AI agents or the remote browser API. If you're comparing approaches, see how remote control browsers differ from local setups.

For the official protocol reference, see the Chrome DevTools Protocol documentation.