BLOG
Playwright CDP Session: Connect to Remote Browsers
Learn how to manage a Playwright CDP session with remote Chromium. Connect, debug, and scale browser automation without local infrastructure.
# Playwright CDP Session: Connect to Remote Browsers
A Playwright CDP session is the connection between your automation script and a Chromium instance over the Chrome DevTools Protocol. When you run Playwright locally, that session is ephemeral—it dies with your process. When you need persistent, scalable, or production-grade browser automation, you need to connect to a remote browser over CDP instead.
This guide explains how Playwright's connectOverCDP works, why you might want a remote browser session, and how to handle the operational realities of running browser workloads across cloud workers, AI agents, and test suites.
What Is a Playwright CDP Session?
Playwright's browserType.connectOverCDP() method attaches your script to an existing Chromium instance via the Chrome DevTools Protocol. Unlike launch(), which spawns a new browser process, connectOverCDP treats the browser as a service you connect to.
import { chromium } from 'playwright';
// Connect to an existing remote browser over CDP
const browser = await chromium.connectOverCDP('wss://remote-browser.dev/playwright?token=YOUR_API_KEY');
// Create a new context (isolated session)
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
});
// Open a page and run automation
const page = await context.newPage();
await page.goto('https://example.com');
await page.click('button[data-testid="submit"]');
// Take a screenshot or extract data
const result = await page.textContent('.result');
// Close the context but keep the browser session alive
await context.close();The key difference from local Playwright usage: the browser process runs elsewhere. Your script is a client, not a server. This matters for several production scenarios.
Why Use a Remote Browser for Playwright CDP Sessions?
Local browser sessions work fine for development. They break down in production for three reasons:
1. Session Persistence Across Workers
Serverless functions, cloud workers, and queue-based architectures are stateless. Each invocation starts fresh. If your Playwright script launches a browser locally, that browser disappears when the function returns.
A Playwright CDP session to a remote browser decouples browser state from compute. You can start a session in one worker, continue it in another, and inspect it from a dashboard. This is essential for long-running AI agent tasks or multi-step automation workflows.
2. Resource Constraints
Chromium is memory-hungry. A single instance can consume 300-500 MB of RAM with several tabs open. Running multiple concurrent Playwright sessions on a small cloud worker will exhaust memory quickly.
Remote browsers shift that resource burden to dedicated infrastructure. Your worker only runs the control logic, not the browser engine.
3. Debugging and Observability
When a Playwright script fails locally, you lose the browser state. With a remote session, you can attach a live viewer, inspect network requests, and replay the session. This is the difference between debugging blind and debugging with full visibility.
Playwright CDP Session vs. Local Launch
| Aspect | Local chromium.launch() | Remote connectOverCDP() |
|---|---|---|
| Browser location | Same machine as script | Hosted infrastructure |
| Session lifetime | Tied to script process | Independent of script |
| Resource usage | Consumes worker memory | Offloaded to browser host |
| Multi-worker support | Not possible | Shared or isolated sessions |
| Live debugging | Limited to local DevTools | Remote viewer and logs |
| Scaling | Manual, per-worker | Centralized browser pool |
| Persistent profiles | Difficult across restarts | Built-in profile storage |
How to Keep Browser Sessions Alive Across Multiple Cloud Workers
The most common production question is: *how do I maintain a browser session when my workers are ephemeral?*
The answer is to separate session ownership from compute. Here's the pattern:
- Provision a browser session via an API call or dedicated service. This returns a connection endpoint (WebSocket URL) and a session ID.
- Store the session ID in your state store (Redis, Postgres, or the provider's session API).
- Connect from any worker using
connectOverCDPwith the session endpoint. - Reconnect on failure—if a worker dies, the next worker picks up the session ID and attaches to the same browser.
// Worker 1: Start a session
const session = await fetch('https://remote-browser.dev/v1/sessions', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.API_KEY}` },
body: JSON.stringify({ persistent: true })
});
const { id, connectUrl } = await session.json();
// Store session ID for other workers
await redis.set(`browser-session:${taskId}`, id);
// Worker 2 (later): Reconnect to the same session
const storedId = await redis.get(`browser-session:${taskId}`);
const browser = await chromium.connectOverCDP(
`wss://remote-browser.dev/sessions/${storedId}/playwright`
);This pattern gives you durable browser state without keeping a worker alive.
Giving AI Agents Browser Access in Production
AI agents that browse the web need more than a browser connection—they need controlled, observable, and safe access. A Playwright CDP session provides the transport, but production agents require additional considerations:
Session Isolation
Each agent task should run in its own browser context. Playwright contexts are lightweight and isolated. Use a fresh context per task, not per browser session. This prevents cross-task data leakage while keeping the overhead of browser startup low.
Persistent Profiles
For agents that need to stay logged in across tasks, use persistent profiles. Remote browser services typically allow you to attach a profile to a session. This stores cookies, localStorage, and other state between connections.
Proxy and IP Management
Websites often block traffic from cloud IP ranges. If your agent needs to access geo-restricted content or avoid bot detection, you'll need configurable proxy settings. Look for a browser service that supports proxy configuration at the session level.
Human Oversight
Production agents should have a human-in-the-loop option. A live viewer that shows the current browser state lets you monitor agent behavior and intervene when necessary. This is non-negotiable for tasks involving purchases, form submissions, or data deletion.
Scaling Playwright Browser Workloads Reliably
Scaling browser automation is not just about adding more workers. It's about managing browser lifecycle, connection pooling, and failure recovery.
Connection Pooling
Opening a new browser session for every task is slow. The browser startup time alone can be 2-5 seconds. Instead, maintain a pool of warm browser sessions and assign tasks to them.
class BrowserPool {
private sessions: Map<string, Browser> = new Map();
async acquire(): Promise<Browser> {
// Reuse an existing session or create a new one
for (const [id, browser] of this.sessions) {
if (browser.isConnected()) {
return browser;
}
}
const browser = await chromium.connectOverCDP(this.getNextEndpoint());
return browser;
}
}Graceful Degradation
Remote browser sessions can drop due to network issues or infrastructure failures. Your code should handle reconnection gracefully. Wrap CDP calls in retry logic and reconnect if the browser disconnects.
Resource Limits
Set limits on concurrent sessions per worker and per account. Unbounded concurrency will exhaust memory and trigger rate limits. Most browser services provide usage controls—use them.
Playwright connectOverCDP: Firefox Support
A common question is whether connectOverCDP works with Firefox. The short answer: no, not reliably.
Playwright's CDP support is Chromium-specific. Firefox uses the WebDriver BiDi protocol for automation, not CDP. While Playwright has experimental Firefox support via connectOverCDP, it's not production-ready and lacks feature parity.
If you need Firefox automation, use Playwright's standard firefox.launch() with a remote browser service that supports Firefox, or use Selenium's WebDriver protocol. For CDP-based sessions, stick with Chromium.
Playwright CDP Session Security Considerations
Connecting to a remote browser over the network introduces security considerations:
Authentication
Never expose a CDP endpoint without authentication. Anyone with the WebSocket URL can control the browser. Use token-based authentication and rotate credentials regularly.
Network Encryption
Always use wss:// (WebSocket Secure) for CDP connections. Plain ws:// sends all browser traffic unencrypted, including cookies and form data.
Session Expiry
Set timeouts on idle sessions. A browser session that stays open indefinitely is a security risk and a resource drain. Most services let you configure session duration and idle timeouts.
When Not to Use a Remote Playwright CDP Session
Remote browser sessions aren't always the right choice. Consider local launches when:
- You're running simple, short-lived tests that don't need persistence.
- You need offline capability or have strict data residency requirements.
- Your workload is small (a few sessions per day) and infrastructure overhead isn't justified.
- You're developing locally and need fast iteration.
The trade-off is operational simplicity versus control. Remote sessions add a network dependency but remove infrastructure management.
Production Checklist for Playwright CDP Sessions
Before deploying browser automation to production, verify:
- [ ] Connection resilience: Your code reconnects if the CDP session drops.
- [ ] Session cleanup: Idle sessions are closed to avoid resource leaks.
- [ ] Authentication: CDP endpoints require tokens and use
wss://. - [ ] Profile persistence: Sessions can restore state across reconnects.
- [ ] Observability: You can view live browser state and logs.
- [ ] Resource limits: Concurrency and session duration are bounded.
- [ ] Proxy support: IP rotation is available if needed for anti-bot measures.
Getting Started with Remote Browser for Playwright
Remote Browser provides hosted Chromium sessions that work with Playwright's connectOverCDP. You get:
- Persistent sessions that survive worker restarts
- Live viewer for real-time debugging
- Profile storage for logged-in states
- Proxy configuration for IP management
- Usage controls to prevent runaway costs
To start a session and get a Playwright CDP connection URL, check the documentation for API details and authentication. For pricing and session limits, see the pricing page.
Related Reading
- Remote Browsers for AI Agents: The Missing Runtime Layer
- Remote Browser Online: Run Real Chromium Without Managing Chrome
- Remote Web Browser: The Practical Runtime for Browser Automation
- Remote Control Browser: When Code and Agents Need to Drive the Web
For the official Playwright documentation on CDP connections, see Playwright's browserType.connectOverCDP reference.
Conclusion
A Playwright CDP session is the foundation for production-grade browser automation. Whether you're building AI agents, running distributed test suites, or orchestrating complex web workflows, connecting to a remote browser decouples your automation from ephemeral compute and gives you persistence, observability, and scale.
The key is to treat browser sessions as infrastructure, not as process-local resources. Use connectOverCDP to attach to hosted Chromium, manage sessions independently of your workers, and build reconnection logic into your automation code.
Start with a simple session, add persistence and profiles as your needs grow, and always keep security and resource limits in mind. Your Playwright automation will be more reliable, easier to debug, and ready for production workloads.