← Blog

BLOG

Playwright Remote Browser: How to Connect and Run Tests in the Cloud

Learn how to connect Playwright to a remote browser in the cloud. A practical guide to CDP, session persistence, and scaling automation.

August 22, 202610 min readRemote Browser

# Playwright Remote Browser: How to Connect and Run Tests in the Cloud

When your Playwright test suite grows beyond a single machine, you hit a wall: local browsers are ephemeral, resource-bound, and hard to share. A Playwright remote browser solves this by moving the Chromium instance to a hosted runtime you can connect to over the network. Instead of launching a browser on your CI runner, you connect to a browser that's already running in the cloud.

This guide explains how to connect Playwright to a remote browser, what to look for in a hosted runtime, and how to keep sessions alive across multiple workers. We'll cover the practical details: CDP endpoints, connection strings, session persistence, and the trade-offs between local and remote execution.

Why Connect Playwright to a Remote Browser?

The standard Playwright workflow is straightforward: chromium.launch() starts a browser on your machine. That works fine for small test suites. But production automation—especially AI agents and large test matrices—needs more:

  • Scalability: You can't run 50 parallel browser instances on a laptop. A remote browser pool scales horizontally.
  • Persistence: Local browsers die when the script exits. Remote sessions can stay alive, keeping cookies, local storage, and login state.
  • Consistency: A hosted Chromium version is identical across runs. No more "works on my machine" failures.
  • Observability: Live viewing and session recording are easier when the browser is a network resource, not a local process.

The core idea is simple: Playwright's connectOverCDP method lets you attach to an existing browser via the Chrome DevTools Protocol. The remote browser exposes a WebSocket endpoint, and your Playwright script becomes a client.

How to Connect Playwright to a Remote Browser

Playwright provides two primary ways to connect to a remote browser: connect() and connectOverCDP(). The right choice depends on whether you control the browser process.

Using connectOverCDP with a Hosted Chromium

If you're using a hosted browser runtime like Remote Browser, you'll typically get a CDP endpoint. Here's a TypeScript example:

import { chromium } from 'playwright';

async function main() {
  // The CDP URL comes from your remote browser provider.
  // It looks like: wss://remote-browser.dev/cdp/your-session-id
  const cdpUrl = process.env.REMOTE_BROWSER_CDP_URL;
  
  if (!cdpUrl) {
    throw new Error('REMOTE_BROWSER_CDP_URL environment variable is not set');
  }

  // Connect to the remote browser over CDP
  const browser = await chromium.connectOverCDP(cdpUrl);
  
  // Get the default context or create a new one
  const context = browser.contexts()[0] || await browser.newContext();
  const page = await context.newPage();

  // Navigate and interact
  await page.goto('https://example.com');
  await page.click('text=More information');
  
  const title = await page.title();
  console.log(`Page title: ${title}`);

  // Don't close the browser if you want to keep the session alive
  // await browser.close();
}

main().catch(console.error);

The key detail: connectOverCDP attaches to an existing browser. You don't call launch(). The browser is already running in the cloud, and your script is just a client.

Using connect() with a Playwright Server

If you're running your own Playwright server (via npx playwright run-server), you'd use connect(). This is more common for internal infrastructure. The hosted approach is simpler because you don't manage the server process.

Keeping Browser Sessions Alive Across Multiple Cloud Workers

One of the most common questions about Playwright remote browsers is session persistence. In a serverless or multi-worker environment, each worker gets a fresh process. If your browser is local, the session dies with the worker.

With a remote browser, the session lives in the cloud. Here's how to keep it alive:

  1. Don't close the browser: In your Playwright script, avoid calling browser.close(). The remote browser stays running until you explicitly terminate it or the session times out.
  2. Reuse the same CDP endpoint: Store the session ID or CDP URL in a shared store (Redis, a database, or an environment variable). Each worker connects to the same endpoint.
  3. Use persistent profiles: A remote browser with persistent profiles saves cookies, local storage, and IndexedDB. When a new worker connects, it gets the same state.

Here's a practical pattern for a multi-worker setup:

// worker-a.ts
import { chromium } from 'playwright';

async function createSession() {
  // This is a simplified example. In practice, you'd use the Remote Browser API
  // to create a session and get a CDP URL.
  const cdpUrl = await createRemoteBrowserSession();
  
  // Store the URL for other workers to use
  await redis.set('browser-session-url', cdpUrl);
  
  const browser = await chromium.connectOverCDP(cdpUrl);
  // ... do work, but don't close the browser
}

// worker-b.ts
import { chromium } from 'playwright';

async function joinSession() {
  const cdpUrl = await redis.get('browser-session-url');
  const browser = await chromium.connectOverCDP(cdpUrl);
  // ... continue where worker-a left off
}

The trade-off: a persistent session is a shared resource. If two workers try to use the same page simultaneously, you'll get conflicts. For true parallelism, create multiple sessions or use separate contexts within the same browser.

Playwright Remote Browser vs. Local Browser: A Comparison

FeatureLocal BrowserRemote Browser (Hosted)
Setup timeInstant, but requires local installRequires API call or config, but no local install
ScalabilityLimited by machine resourcesScales horizontally with the provider
Session persistenceDies with the processCan persist across workers and restarts
Network accessLocal network onlyCan use proxies and different IPs
ObservabilityLimited to local DevToolsLive viewer, session recording, logs
Resource usageConsumes local CPU/RAMZero local overhead
CostFree (but you pay for CI runners)Metered per browser-hour
Browser versionTied to local installProvider controls versioning
Stealth/proxy settingsManual configurationConfigurable via provider settings

The comparison table highlights the key difference: a remote browser is infrastructure, not a process. You pay for it by the hour, but you get persistence, scale, and observability that local browsers can't provide.

What to Look for in a Playwright Remote Browser Provider

Not all remote browser services are equal. When evaluating a provider, consider these production criteria:

1. CDP Compatibility

The provider must expose a standard CDP WebSocket endpoint. If it doesn't, Playwright's connectOverCDP won't work. Check for explicit Playwright support in the documentation.

2. Session Lifecycle Controls

You need to control when sessions start and end. Look for:

  • Session creation via API: Programmatic creation of new browser sessions.
  • Idle timeout configuration: How long a session stays alive without activity.
  • Manual termination: The ability to kill a session explicitly.

3. Persistent Profiles

For AI agents and automation that need login state, persistent profiles are essential. The provider should save browser state between sessions, not just within a single session.

4. Live Debugging

When something goes wrong, you need to see what the browser is doing. A live viewer (a video feed or interactive DevTools) is critical for debugging remote sessions.

5. Proxy and IP Controls

If you're scraping or testing geo-restricted content, you need configurable proxy settings. The provider should let you set a proxy per session or per context.

6. Usage Controls

Metered pricing means you need guardrails. Look for:

  • Concurrency limits: How many parallel sessions you can run.
  • Timeout settings: Maximum session duration.
  • Cost alerts: Notifications when usage approaches a threshold.

Common Pitfalls and How to Avoid Them

Pitfall 1: Closing the Browser Too Early

The most common mistake is treating a remote browser like a local one. If you call browser.close(), you terminate the session. For persistent sessions, you need to detach instead.

Fix: Use browser.close() only when you're done with the session. For long-running tasks, keep the browser open and manage the session lifecycle via the provider's API.

Pitfall 2: Ignoring Context Isolation

Playwright contexts are isolated by default. If you create a new context in a remote browser, it starts with a clean state. This is good for security but can be confusing if you expect shared state.

Fix: Use the default context or explicitly share cookies/storage via context.addCookies() or context.storageState().

Pitfall 3: Assuming Network Parity

A remote browser runs in a data center, not on your machine. The network conditions, IP address, and available fonts are different. Tests that pass locally might fail remotely due to network latency or IP-based blocking.

Fix: Test your automation against the remote browser early. Use the live viewer to verify behavior, and configure proxy settings if you need a specific IP range.

Pitfall 4: Not Handling WebSocket Disconnects

connectOverCDP relies on a WebSocket connection. If the connection drops (network blip, provider restart), your script will throw an error.

Fix: Implement retry logic. Catch connection errors and reconnect to the same session. Most providers keep the browser alive even if the client disconnects.

When Not to Use a Playwright Remote Browser

A remote browser isn't always the right answer. Consider local execution when:

  • You're running a tiny test suite: A few tests on a CI runner don't need a remote browser.
  • You need offline development: You can't connect to a cloud browser without internet.
  • You have strict data residency requirements: Some data can't leave your infrastructure.

For everything else—AI agents, large test matrices, persistent login sessions, or geo-distributed testing—a remote browser is the more practical choice.

Production-Ready Playwright Remote Browser Setup

Here's a checklist for moving from local to remote Playwright:

  1. Choose a provider that supports CDP and offers session persistence. Remote Browser provides hosted Chromium with CDP access and Playwright compatibility. See the documentation for connection details.
  2. Create a session via the provider's API. Store the CDP URL securely (e.g., in a secrets manager).
  3. Write your Playwright script using connectOverCDP. Handle connection errors with retry logic.
  4. Configure session lifecycle: Set idle timeouts and maximum session duration to control costs. Check pricing for current limits.
  5. Use persistent profiles for login state. This is critical for AI agents that need to maintain context across tasks.
  6. Set up monitoring: Use the live viewer and session logs to debug failures. Integrate with your existing observability stack.

The Role of CDP in Playwright Remote Browser

The Chrome DevTools Protocol is the foundation of remote browser control. Playwright's connectOverCDP method speaks CDP directly, which means you can connect to any browser that exposes a CDP endpoint—not just Playwright-managed browsers.

This is powerful because it decouples your test code from the browser lifecycle. The browser can be running in a Docker container, a cloud VM, or a hosted service. Your Playwright script just needs the WebSocket URL.

For more details on CDP, see the official Chrome DevTools Protocol documentation. Understanding CDP helps you debug connection issues and leverage advanced features like performance tracing or network interception.

Scaling Playwright Remote Browser for AI Agents

AI agents are a growing use case for remote browsers. Unlike traditional tests, agents need to:

  • Maintain context across multiple steps and API calls.
  • Handle dynamic pages that change based on user interaction.
  • Run for extended periods (minutes to hours).

A remote browser is well-suited for this. The session persists while the agent thinks, and the agent can reconnect if the process restarts. This is why many AI agent frameworks use hosted browsers rather than local ones.

For a deeper dive into how remote browsers fit into AI agent workflows, read our post on remote browsers for AI agents. It covers session management, profile persistence, and the trade-offs between local and hosted runtimes.

Conclusion

A Playwright remote browser is the missing piece for scaling browser automation beyond a single machine. By connecting to a hosted Chromium instance via CDP, you get persistence, scalability, and observability that local browsers can't provide.

The key takeaways:

  • Use connectOverCDP to attach to a remote browser. Don't call launch().
  • Keep sessions alive by not closing the browser and reusing the same CDP endpoint.
  • Evaluate providers on CDP compatibility, session lifecycle controls, and persistent profiles.
  • Handle WebSocket disconnects with retry logic.
  • Use remote browsers when you need scale, persistence, or geo-distributed testing.

Ready to move your Playwright tests to the cloud? Explore Remote Browser's hosted Chromium runtime and see how it fits into your automation stack. For a broader view of browser automation without the infrastructure headache, check out our guide to remote web browsers.