BLOG
Connect Over CDP Playwright: Drive Remote Chrome Instances
Connect over CDP Playwright to control hosted Chromium remotely. Learn the setup, trade-offs, and production patterns for AI agents and automation.
# Connect Over CDP Playwright: Drive Remote Chrome Instances
If you need to connect over CDP Playwright to a browser that isn't running on your local machine, you're solving a real infrastructure problem. The Chrome DevTools Protocol (CDP) is the wire protocol that lets tools like Playwright drive Chromium. When you use playwright.connectOverCDP(), you attach your automation code to an existing browser process—local or remote—rather than launching a fresh one.
This pattern matters for AI agents, long-running automation, and teams that want browser sessions to outlive a single script execution. This guide covers how to connect over CDP with Playwright, what the trade-offs are, and how to use it in production with hosted Chromium.
Why Connect Over CDP Instead of Launching a Browser?
Playwright's default workflow is chromium.launch(). That starts a new browser process, opens a fresh profile, and gives you a clean slate. It's simple and works for most test suites.
But connectOverCDP solves a different problem: attaching to a browser that already exists.
Here's when you want it:
- You need a persistent session. A browser that stays alive across multiple script runs, cloud workers, or agent steps.
- You want to debug live. Connect to a browser you can watch in real time, inspect the DOM, and see what the agent is doing.
- You're using a remote browser service. The browser runs in the cloud; your code connects to it over CDP.
- You need to share a browser across processes. Multiple workers attach to the same session without relaunching.
The core difference: launch() creates a browser; connectOverCDP() attaches to one.
How to Connect Over CDP with Playwright
The API is straightforward. You point Playwright at a CDP endpoint, and it returns a Browser object you can use like any other.
import { chromium } from 'playwright';
// Connect to an existing Chrome instance via CDP
const browser = await chromium.connectOverCDP('http://localhost:9222');
// Get the default context (the one the browser was launched with)
const context = browser.contexts()[0];
// Create a new page in that context
const page = await context.newPage();
// Drive the browser as usual
await page.goto('https://example.com');
console.log(await page.title());
// Don't close the browser—it belongs to someone else
// await browser.close();The key detail: when you connect over CDP, you don't own the browser lifecycle. Closing the Browser object from Playwright disconnects your client, but the underlying Chrome process keeps running. That's the point—someone else (or another process) can connect later.
Connecting to a Remote CDP Endpoint
The same API works for remote browsers. Instead of localhost, you use the remote host's CDP URL:
const browser = await chromium.connectOverCDP('wss://remote-browser.example.com/cdp');WebSocket (WSS) is the standard transport for remote CDP connections. Most hosted browser services expose a WSS endpoint that speaks CDP.
CDP vs. Playwright's Own Protocol
Playwright has its own protocol that wraps CDP. When you use connectOverCDP, you're bypassing Playwright's protocol and speaking CDP directly. This has implications:
| Aspect | chromium.launch() | connectOverCDP() |
|---|---|---|
| Browser lifecycle | Playwright owns it | External process owns it |
| Session persistence | Lost on close | Survives disconnects |
| Debugging | Headless by default | Can attach to visible browser |
| Multi-client | Single client | Multiple clients can attach |
| Setup complexity | Low | Requires running browser with CDP |
| Use case | Tests, short scripts | AI agents, long-running tasks |
The trade-off is control. With launch(), Playwright manages everything. With connectOverCDP(), you get flexibility but must handle the browser lifecycle yourself.
Playwright connect_over_cdp Firefox: What's Supported?
A common question: does connectOverCDP work with Firefox?
The short answer: CDP is a Chromium protocol. Firefox doesn't speak CDP natively. Playwright's Firefox support uses a different mechanism (the Firefox DevTools Protocol, or a Playwright-specific driver).
The official Playwright docs state that connectOverCDP is for Chromium-based browsers. If you need to connect to Firefox, you'd use firefox.launch() or firefox.connect() with Playwright's own protocol—not CDP.
For production AI agent workloads, Chromium is the pragmatic choice. It's the most widely supported browser for automation, and CDP gives you the deepest control.
How to Keep Browser Sessions Alive Across Multiple Cloud Workers
This is the question that drives most people to connectOverCDP. You have a cloud worker that starts a browser, does some work, and dies. The next worker needs the same session.
The naive approach: each worker launches its own browser. That works, but you lose state—cookies, localStorage, logged-in sessions—and you pay the startup cost every time.
The better approach: run a persistent browser in a separate process or service, and have workers connect over CDP.
Here's the pattern:
- Start a browser with a remote debugging port. This can be a dedicated VM, a container, or a hosted browser service.
- Expose the CDP endpoint. Either as
http://host:portorws://host:port. - Workers connect via `connectOverCDP()`. Each worker attaches to the same browser, uses the same context, and shares state.
- Handle disconnects gracefully. If a worker dies, the browser stays alive. The next worker reconnects.
This is exactly what hosted browser services like Remote Browser provide. You get a persistent Chromium session in the cloud, and your code connects to it over CDP from anywhere.
How to Give Your AI Agent Browser Access in Production
AI agents need browser access for a growing list of tasks: form filling, data extraction, navigation, and multi-step workflows. But giving an agent a browser is different from giving it an API.
The production requirements are:
- Session persistence. Agents work over minutes or hours. The browser must survive between steps.
- Isolation. Different agents or tasks shouldn't interfere with each other.
- Observability. You need to see what the agent is doing, especially when it fails.
- Scalability. Multiple agents running concurrently need multiple browser sessions.
connectOverCDP solves the first two. The browser is persistent and isolated per session. For observability, you need a way to view the browser—either through a live viewer or by capturing screenshots and DOM snapshots.
This is where a hosted runtime helps. Instead of managing your own browser fleet, you use a service that provides:
- Hosted Chromium sessions with CDP endpoints
- Persistent profiles that survive disconnects
- Live debugging via a web viewer
- Proxy and stealth settings to avoid bot detection
Your agent code connects over CDP, does its work, and disconnects. The browser stays ready for the next step.
What Is a Browser Agent?
The term "browser agent" gets thrown around a lot. In practice, it means one of two things:
- An AI agent that uses a browser to complete tasks. The agent receives a goal, breaks it into steps, and uses browser automation to execute them.
- A tool that controls a browser on behalf of an agent. This is the runtime layer—the code that translates agent decisions into browser actions.
When people ask "what is a browser agent in task manager," they're usually seeing a process related to browser automation. It could be a Playwright script, a Puppeteer process, or a hosted browser service's client.
For AI agents, the browser agent is the bridge between the LLM's decisions and the browser's actions. It handles:
- Navigation (goto, click, type)
- State extraction (DOM, screenshots, accessibility tree)
- Action execution (clicking, form filling, scrolling)
- Error recovery (retry, fallback, logging)
The quality of this layer determines whether your agent succeeds or fails in production.
Agent Control Browser: The Runtime Layer
"Agent control browser" is another way to describe the runtime that gives AI agents browser access. The key word is control.
An agent needs more than a browser API. It needs:
- Reliable connections that don't drop mid-task
- Session management that keeps state across steps
- Resource limits so one agent can't consume everything
- Logging and replay for debugging failures
When you connect over CDP Playwright, you get the low-level control. But you still need to build the runtime around it.
A hosted browser service provides this runtime. You get:
- CDP endpoints for Playwright, Puppeteer, or raw CDP clients
- Session APIs for creating and managing browser sessions
- Live viewers for real-time debugging
- Usage controls to cap spending and prevent runaway agents
The result: your agent code stays simple. It connects, does work, and disconnects. The runtime handles the hard parts.
Production Patterns for CDP Connections
Based on real-world usage, here are the patterns that work:
1. Reconnect with Retry
CDP connections drop. Networks hiccup. Browsers restart. Your code should handle this:
async function connectWithRetry(endpoint: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await chromium.connectOverCDP(endpoint);
} catch (err) {
if (i === maxRetries - 1) throw err;
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}2. Use a Single Context
When you connect over CDP, the browser may have multiple contexts. For most agent workloads, you want one context per session. This keeps cookies and localStorage isolated.
3. Don't Close the Browser
Remember: browser.close() disconnects your client. If you want the session to persist, use browser.close() only when you're done with the session entirely. For short tasks, just disconnect.
4. Monitor Resource Usage
Long-running browsers consume memory and CPU. Set up monitoring to detect leaks and restart sessions when needed.
Remote Browser: Hosted Chromium with CDP Access
Remote Browser provides exactly this: hosted Chromium sessions you can connect to over CDP with Playwright, Puppeteer, or raw CDP clients.
The workflow:
- Create a session via the API or dashboard.
- Get the CDP endpoint (WSS URL).
- Connect with Playwright using
connectOverCDP(). - Run your automation—tests, AI agent tasks, data extraction.
- Disconnect when done. The session persists for the next connection.
Key features for production:
- Persistent profiles so logins and cookies survive across sessions
- Live viewer to watch the browser in real time
- Configurable browser settings for proxy and stealth requirements
- Session isolation so different tasks don't interfere
For AI agents, this means you can give your agent a browser that stays alive across multiple steps, survives worker restarts, and can be debugged live.
When Not to Use connectOverCDP
connectOverCDP isn't always the right answer. Consider the alternatives:
- Short, stateless tasks: If each task is independent and doesn't need shared state,
chromium.launch()is simpler and faster. - Parallel execution at scale: If you need 100 concurrent browsers, launching fresh instances is often easier than managing 100 persistent sessions.
- Firefox or WebKit: CDP is Chromium-only. If you need cross-browser testing, use Playwright's native protocol.
The rule of thumb: use connectOverCDP when you need persistence, debugging, or multi-client access. Use launch() when you need simplicity and scale.
Getting Started
To connect over CDP Playwright with Remote Browser:
- Create an account and get your API key.
- Create a browser session via the API.
- Get the CDP endpoint from the session details.
- Connect with Playwright using the code above.
For more details, check the documentation for API reference and examples. If you're building AI agents, see our guide on remote browsers for AI agents for architecture patterns.
Conclusion
Connecting over CDP Playwright is the right approach when you need to control a browser that isn't local. It gives you persistent sessions, live debugging, and multi-client access—all essential for production AI agents and long-running automation.
The trade-off is complexity. You're responsible for the browser lifecycle, connection handling, and resource management. A hosted runtime like Remote Browser handles these for you, so you can focus on your automation logic.
Start with a simple connection, add retry logic, and build up to persistent sessions. The pattern scales from a single script to a fleet of AI agents.