Skip to content
Learn Agentic AI12 min read0 views

Playwright Browser Contexts: Isolated Sessions for Multi-Account AI Agents

Learn how to use Playwright browser contexts to create isolated sessions with separate cookies, storage, and authentication state for multi-account AI agents with proxy rotation.

What Are Browser Contexts and Why Do AI Agents Need Them?

A browser context in Playwright is equivalent to an incognito browser profile. Each context has its own cookies, local storage, session storage, and cache — completely isolated from other contexts. Critically, multiple contexts can run simultaneously within a single browser instance, sharing the browser process but maintaining complete session isolation.

For AI agents, contexts solve a fundamental problem: running multiple independent sessions without launching separate browser processes. An agent can manage five different user accounts, each authenticated separately, all within one browser. This is more memory-efficient than launching five separate browsers and faster than sequentially logging in and out of a single session.

Creating and Using Browser Contexts

The basic pattern for creating isolated contexts:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()

    # Create two isolated contexts
    context_a = browser.new_context()
    context_b = browser.new_context()

    # Each context has its own page(s)
    page_a = context_a.new_page()
    page_b = context_b.new_page()

    # Navigate independently
    page_a.goto("https://example.com")
    page_b.goto("https://example.com")

    # Actions in context_a do not affect context_b
    # Cookies set in page_a are invisible to page_b

    context_a.close()
    context_b.close()
    browser.close()

Configuring Contexts with Different Identities

Each context can have its own viewport, user agent, locale, timezone, and geolocation:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()

    # Desktop user in New York
    desktop_context = browser.new_context(
        viewport={"width": 1920, "height": 1080},
        user_agent=(
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
        ),
        locale="en-US",
        timezone_id="America/New_York",
        geolocation={"latitude": 40.7128, "longitude": -74.0060},
        permissions=["geolocation"],
    )

    # Mobile user in London
    mobile_context = browser.new_context(
        viewport={"width": 375, "height": 812},
        user_agent=(
            "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) "
            "AppleWebKit/605.1.15 Mobile/15E148"
        ),
        locale="en-GB",
        timezone_id="Europe/London",
        geolocation={"latitude": 51.5074, "longitude": -0.1278},
        permissions=["geolocation"],
        is_mobile=True,
        has_touch=True,
    )

    desktop_page = desktop_context.new_page()
    mobile_page = mobile_context.new_page()

    # Same URL, different experiences
    desktop_page.goto("https://example.com")
    mobile_page.goto("https://example.com")

    desktop_page.screenshot(path="desktop_view.png")
    mobile_page.screenshot(path="mobile_view.png")

    desktop_context.close()
    mobile_context.close()
    browser.close()

Saving and Restoring Authentication State

One of the most powerful context features is persisting and restoring session state:

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

from playwright.sync_api import sync_playwright

# Step 1: Login and save the authentication state
def save_auth_state(login_url, username, password, state_file):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context()
        page = context.new_page()

        page.goto(login_url)
        page.get_by_label("Username").fill(username)
        page.get_by_label("Password").fill(password)
        page.get_by_role("button", name="Sign In").click()
        page.wait_for_url("**/dashboard**")

        # Save cookies, local storage, session storage
        context.storage_state(path=state_file)
        print(f"Auth state saved to {state_file}")

        context.close()
        browser.close()

# Step 2: Use saved state in future sessions
def use_saved_auth(state_file):
    with sync_playwright() as p:
        browser = p.chromium.launch()

        # Load the saved authentication state
        context = browser.new_context(storage_state=state_file)
        page = context.new_page()

        # Navigate directly to authenticated pages
        page.goto("https://example.com/dashboard")
        print(f"Logged in as: {page.locator('.user-name').text_content()}")

        context.close()
        browser.close()

# Save once
save_auth_state(
    "https://example.com/login",
    "ai_agent", "password123",
    "auth_state.json"
)

# Reuse many times
use_saved_auth("auth_state.json")

Managing Cookies Directly

For fine-grained cookie control:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    context = browser.new_context()

    # Add cookies before navigation
    context.add_cookies([
        {
            "name": "session_id",
            "value": "abc123",
            "domain": "example.com",
            "path": "/",
            "httpOnly": True,
            "secure": True,
        },
        {
            "name": "preferences",
            "value": "dark_mode=true",
            "domain": "example.com",
            "path": "/",
        },
    ])

    page = context.new_page()
    page.goto("https://example.com")

    # Read current cookies
    cookies = context.cookies()
    for cookie in cookies:
        print(f"{cookie['name']}: {cookie['value']}")

    # Clear all cookies
    context.clear_cookies()

    context.close()
    browser.close()

Proxy Rotation with Contexts

Each context can use a different proxy, enabling IP rotation for scraping agents:

from playwright.sync_api import sync_playwright

PROXIES = [
    {"server": "http://proxy1.example.com:8080"},
    {"server": "http://proxy2.example.com:8080"},
    {"server": "http://proxy3.example.com:8080",
     "username": "user", "password": "pass"},
]

def scrape_with_proxy_rotation(urls: list[str]):
    with sync_playwright() as p:
        browser = p.chromium.launch()
        results = []

        for i, url in enumerate(urls):
            proxy = PROXIES[i % len(PROXIES)]

            context = browser.new_context(proxy=proxy)
            page = context.new_page()

            try:
                page.goto(url, wait_until="networkidle", timeout=15000)
                results.append({
                    "url": url,
                    "title": page.title(),
                    "proxy": proxy["server"],
                })
            except Exception as e:
                print(f"Failed {url} via {proxy['server']}: {e}")
            finally:
                context.close()

        browser.close()
        return results

Multi-Account Agent Pattern

Here is a complete pattern for an AI agent managing multiple accounts simultaneously:

from dataclasses import dataclass
from playwright.sync_api import sync_playwright, BrowserContext

@dataclass
class AccountSession:
    username: str
    context: BrowserContext
    page: object  # Page type

class MultiAccountAgent:
    def __init__(self):
        self.sessions: dict[str, AccountSession] = {}

    def add_account(self, browser, username: str, state_file: str):
        context = browser.new_context(storage_state=state_file)
        page = context.new_page()
        self.sessions[username] = AccountSession(
            username=username,
            context=context,
            page=page,
        )
        print(f"Loaded session for {username}")

    def perform_action(self, username: str, action_fn):
        session = self.sessions[username]
        return action_fn(session.page)

    def close_all(self):
        for session in self.sessions.values():
            session.context.close()
        self.sessions.clear()

# Usage
with sync_playwright() as p:
    browser = p.chromium.launch()
    agent = MultiAccountAgent()

    # Load saved authentication states
    agent.add_account(browser, "user_alice", "auth_alice.json")
    agent.add_account(browser, "user_bob", "auth_bob.json")

    # Perform actions on different accounts
    alice_data = agent.perform_action(
        "user_alice",
        lambda page: (
            page.goto("https://example.com/dashboard"),
            page.locator(".balance").text_content(),
        )
    )

    bob_data = agent.perform_action(
        "user_bob",
        lambda page: (
            page.goto("https://example.com/dashboard"),
            page.locator(".balance").text_content(),
        )
    )

    agent.close_all()
    browser.close()

FAQ

How many browser contexts can run simultaneously in one browser?

There is no hard-coded limit in Playwright. The practical limit depends on available memory. Each context uses approximately 10-30 MB of RAM depending on the pages loaded. On a machine with 8 GB of RAM, you can comfortably run 50-100 lightweight contexts. For memory-constrained environments, create contexts on demand and close them after use rather than keeping all of them open.

Do browser contexts share the browser cache?

No. Each context has its own isolated cache, cookies, and storage. This means the same resource (JavaScript file, image, CSS) may be downloaded separately for each context. If you need shared caching to reduce bandwidth, use a caching proxy between Playwright and the internet rather than relying on browser-level caching.

Can I transfer cookies or storage from one context to another?

Yes. Export the state from one context with context_a.storage_state() (returns a dictionary) and pass it to another context with browser.new_context(storage_state=state_dict). You can also selectively read cookies from one context and add them to another using context.cookies() and context.add_cookies().


#BrowserContexts #SessionIsolation #MultiAccount #Playwright #ProxyRotation #AIAgents #WebAutomation

Share this article
C

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.