Back to Integrations
Integration Guide

Playwright Proxy Integration

Jun 11, 2026 9 min read Databay Research Team

Configure Databay residential and datacenter proxies in Playwright with the built-in proxy option, including username and password authentication, per-context proxies for rotation, country targeting and sticky sessions, plus fixes for 407 errors, tunnel failures, TLS pitfalls and timeout tuning in Node.js and Python.

Playwright Proxy Integration

What Is Playwright

Playwright is Microsoft's browser automation framework, driving Chromium, Firefox and WebKit from a single API with bindings for Node.js, Python, Java and .NET. It has become the default for new automation projects largely because of its ergonomics: auto-waiting, isolated browser contexts, and network interception are first-class. For proxy users it has a decisive advantage over both Puppeteer and Selenium: the proxy option accepts a username and password directly, so authenticated proxies work out of the box with no extensions, no auth-popup workarounds and no third-party wrappers. It is the easiest of the major browser tools to pair with a proxy network.

Connecting Playwright to Databay Proxies

Databay exposes one gateway, gw.databay.co:8888, and you choose the pool, country and session behaviour with flags appended to the username: USER-zone-residential for the residential pool, USER-zone-datacenter for datacenter, plus optional -countryCode-us and -sessionId-abc123 flags. On the Playwright side everything goes through the proxy object, which can be set at browser launch (applies to every context) or per context (each context gets its own proxy and exit identity).

Residential Proxy Setup

The launch-level setup in Node.js routes the entire browser through the residential pool:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://gw.databay.co:8888',
      username: 'USER-zone-residential',
      password: 'PASS'
    }
  });

  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  console.log(await page.textContent('body'));

  await browser.close();
})();

Keep the credentials in the username and password fields rather than embedding them in the server URL: Chromium strips credentials from proxy URLs, and the dedicated fields are how Playwright answers the gateway's authentication challenge for all three browser engines consistently.

Datacenter Proxy Setup

The API is identical in every language binding; here is the datacenter pool in Python:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        'server': 'http://gw.databay.co:8888',
        'username': 'USER-zone-datacenter',
        'password': 'PASS'
    })
    page = browser.new_page()
    page.goto('https://httpbin.org/ip')
    print(page.text_content('body'))
    browser.close()

Datacenter IPs are faster and cheaper per gigabyte; residential IPs come from real consumer connections and survive reputation-based blocking. A pragmatic split: datacenter for permissive, high-volume targets, residential for protected or geo-sensitive ones. Since the pool is a username flag, switching is a one-word change.

Per-Context Proxies

Playwright's killer feature for proxy work is that browser.newContext() accepts its own proxy option, so one browser process can run several isolated identities, each with its own exit IP, cookies and storage:

const browser = await chromium.launch();

const usContext = await browser.newContext({
  proxy: {
    server: 'http://gw.databay.co:8888',
    username: 'USER-zone-residential-countryCode-us',
    password: 'PASS'
  }
});

const deContext = await browser.newContext({
  proxy: {
    server: 'http://gw.databay.co:8888',
    username: 'USER-zone-residential-countryCode-de',
    password: 'PASS'
  }
});

One honest compatibility note: on some older Playwright/Chromium combinations, per-context proxies were only honoured if the browser itself was launched with a proxy; the documented workaround was to launch with a placeholder such as proxy: { server: 'http://per-context' }. Current releases handle per-context proxies directly, but if contexts unexpectedly use your real IP on an older pin, that workaround is the fix.

Country Targeting and Sticky Sessions

Both behaviours live in the username. -countryCode-us pins the exit country; -sessionId-abc123 pins a single exit IP for as long as that session id is reused, which is what a logged-in, multi-page flow needs:

const context = await browser.newContext({
  proxy: {
    server: 'http://gw.databay.co:8888',
    username: 'USER-zone-residential-countryCode-us-sessionId-abc123',
    password: 'PASS'
  }
});

The session id is any string you generate. The pairing of one sticky session to one browser context is the natural unit of identity in Playwright: cookies, cache and exit IP all live and die together.

Proxy Rotation Patterns

Because contexts are cheap and carry their own proxy, rotation in Playwright is simply context lifecycle management. A page load opens many parallel connections, so you do not want rotation mid-page: an unpinned rotating session can render one page from several IPs simultaneously, which is itself a detection signal. Instead, pin each context to a fresh sticky session and rotate by replacing the context:

function freshProxy() {
  const id = Math.random().toString(36).slice(2, 10);
  return {
    server: 'http://gw.databay.co:8888',
    username: `USER-zone-residential-sessionId-${id}`,
    password: 'PASS'
  };
}

const browser = await chromium.launch();

for (const url of urls) {
  const context = await browser.newContext({ proxy: freshProxy() });
  const page = await context.newPage();
  try {
    await page.goto(url, { waitUntil: 'domcontentloaded' });
    // ... extract ...
  } finally {
    await context.close();
  }
}

For parallel work, run a small pool of contexts, each on its own session id, and replace any context whose session starts returning 403s, 429s or CAPTCHAs. This keeps healthy exit IPs in service while quietly retiring blocked ones. The strategy behind sticky-versus-rotating choices is covered in static vs rotating proxies.

Common Errors and Fixes

Playwright surfaces proxy failures with engine-specific error strings. The four families below account for nearly all of them.

HTTP 407 Proxy Authentication Required

A 407 means the gateway rejected or never received credentials. In Playwright the common causes are credentials embedded in the server URL instead of the username/password fields, a typo in the zone or flag spelling (use the exact forms countryCode and sessionId), or stale credentials. Validate outside the browser first:

curl -x http://USER-zone-residential:PASS@gw.databay.co:8888 https://httpbin.org/ip

If curl succeeds, recheck the proxy object: server carries only scheme, host and port; everything else belongs in the dedicated fields.

ERR_TUNNEL_CONNECTION_FAILED

Chromium reports net::ERR_TUNNEL_CONNECTION_FAILED when the HTTPS CONNECT tunnel fails; Firefox surfaces the same condition as NS_ERROR_PROXY_CONNECTION_REFUSED. Check the endpoint spelling (gw.databay.co:8888), then the username flags, since a malformed flag can make the gateway refuse the tunnel outright. If the error appears only for one target while httpbin.org/ip works, the target is rejecting that exit IP: rotate to a fresh session id rather than debugging configuration. If it appears only under load, you may be exhausting local sockets or file descriptors before the proxy is ever at fault; reduce parallel contexts and retest.

TLS and Certificate Errors

HTTPS traffic through the gateway is tunnelled end-to-end; the proxy does not re-sign certificates. Certificate errors in Playwright therefore usually trace to corporate TLS interception on your own network, a misconfigured target, or an outdated browser bundle (keep Playwright and its bundled browsers updated together). The escape hatch is ignoreHTTPSErrors: true on the context, appropriate for staging servers with self-signed certificates, but unwise as a permanent default: it silences exactly the warning that detects interception. Also remember that IP rotation does not change your TLS fingerprint; how fingerprinting interacts with proxies is explained in TLS fingerprinting and proxy detection.

Timeouts and Slow Pages

Residential exits add per-connection latency, and Playwright's 30-second default navigation timeout can be tight for heavy pages. Raise the timeout, wait for less, and block what you do not need:

context.setDefaultNavigationTimeout(60000);

// Block heavy resources: faster pages, less metered bandwidth
await context.route('**/*', (route) => {
  const type = route.request().resourceType();
  return ['image', 'media', 'font'].includes(type)
    ? route.abort()
    : route.continue();
});

await page.goto(url, { waitUntil: 'domcontentloaded' });

Waiting for domcontentloaded instead of networkidle avoids stalling on analytics and long-polling connections. The routing rule does double duty on metered residential plans: images, media and fonts are usually the bulk of page weight and rarely needed for extraction. If one context times out repeatedly while siblings are fine, its exit IP is slow; replace the session instead of raising timeouts further.

Best Practices for Playwright with Proxies

  • Context = identity. Give each logical identity one context, one sticky sessionId, one cookie jar. Never share a session id across concurrent contexts.
  • Rotate on evidence. Replace a context's session after blocks or CAPTCHAs, not after every request; unblocked IPs are worth keeping warm.
  • Block heavy resources. A context.route() rule that aborts images, media and fonts cuts both runtime and bandwidth spend.
  • Use per-context geo for comparisons. Parallel contexts with different countryCode flags let one process compare localized pricing or content side by side.
  • Mind the non-IP signals. Automation fingerprints and TLS characteristics survive IP rotation; see how sites detect headless browsers for what else targets check.
  • Verify at startup. A page.goto('https://httpbin.org/ip') health check per context confirms wiring and logs the exit IP for debugging.

For broader strategy beyond browser configuration, the web scraping with proxies guide covers planning, pool selection and block recovery.

Frequently Asked Questions

Do per-context proxies work in all three Playwright browsers?
Yes, newContext({ proxy }) is supported for Chromium, Firefox and WebKit. On some older Playwright/Chromium combinations the browser had to be launched with a placeholder proxy for per-context values to take effect; current releases do not need that, but it remains the documented workaround if you are pinned to an old version.
Can I rotate proxies without restarting the browser?
Yes, and it is the idiomatic pattern: close the context and open a new one with a different proxy object or a fresh sessionId. Contexts are lightweight compared to browser launches, so per-task rotation costs very little. An existing context's proxy cannot be changed in place.
Should proxy credentials go in the server URL or the username and password fields?
Always the dedicated fields. Chromium strips credentials embedded in proxy URLs, and Playwright's username/password fields are the supported, engine-consistent way to answer the gateway's 407 challenge across Chromium, Firefox and WebKit.
Does Playwright support SOCKS5 proxies?
Playwright accepts socks5:// in the proxy server option, but Chromium does not support SOCKS5 with authentication, so credential-based access over SOCKS5 will fail there. Databay supports both HTTP and SOCKS5; with Playwright the authenticated HTTP gateway is the dependable choice.
Should I use residential or datacenter proxies with Playwright?
Datacenter for speed and cost on permissive targets; residential for targets that score IP reputation, enforce geo-restrictions or sit behind aggressive bot defence. Because the pool is selected by a username flag, you can mix both in one browser by giving different contexts different credentials.

Start Using Databay Proxies Today

Set up residential, datacenter, or mobile proxies in minutes. Pay as you go with no commitments.

Start Using Rotating Proxies Today

Join 8,000+ users using Databay's rotating proxy infrastructure for web scraping, data collection, and automation. Access 34M+ residential, datacenter, and mobile IPs across 200+ countries from a flat $0.55/GB (Flex), pay-as-you-go. No monthly commitment, no connection limits - start collecting data in minutes.