Skip to content
Learn Agentic AI
Learn Agentic AI12 min read7 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:

flowchart LR
    AGENT(["Agent wants<br/>to run code"])
    POLICY{"Policy check<br/>allow list"}
    SANDBOX[("Ephemeral sandbox<br/>Firecracker or gVisor")]
    NETPOL["Egress firewall<br/>deny by default"]
    LIMIT["Resource limits<br/>CPU, mem, time"]
    EXEC["Run untrusted code"]
    LOG[("Audit log")]
    OUT(["Captured stdout<br/>or error"])
    DENY(["Refuse"])
    AGENT --> POLICY
    POLICY -->|Allow| SANDBOX
    POLICY -->|Block| DENY
    SANDBOX --> NETPOL --> LIMIT --> EXEC --> LOG --> OUT
    style POLICY fill:#f59e0b,stroke:#d97706,color:#1f2937
    style SANDBOX fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
    style EXEC fill:#4f46e5,stroke:#4338ca,color:#fff
    style OUT fill:#059669,stroke:#047857,color:#fff
    style DENY fill:#dc2626,stroke:#b91c1c,color:#fff
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:

Hear it before you finish reading

Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.

Try Live Demo →
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:

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:

Still reading? Stop comparing — try CallSphere live.

CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.

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

Try CallSphere AI Voice Agents

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

Related Articles You May Like

Agentic AI

LangGraph Checkpointers in Production: Durable, Resumable Agents with Eval Replay

Use LangGraph's checkpointer to make agents resumable across crashes and human-in-the-loop pauses, then replay any checkpoint into your eval pipeline.

Agentic AI

Browser Agents with LangGraph + Playwright: Visual Evaluation Pipelines That Don't Lie

Build a browser agent with LangGraph and Playwright that does multi-step web tasks, then ground-truth its work with visual diffs and DOM-based evaluators.

Agentic AI

LangGraph State-Machine Architecture: A Principal-Engineer Deep Dive (2026)

How LangGraph's StateGraph, channels, and reducers actually work — with a working multi-step agent, eval hooks at every node, and the patterns that survive production.

Agentic AI

OpenAI Computer-Use Agents (CUA) in Production: Build + Evaluate a Real Workflow (2026)

Build a working computer-use agent with the OpenAI Computer Use tool — clicks, types, scrolls a real browser — then evaluate task success on a benchmark suite.

Agentic AI

Building Your First Agent with the OpenAI Agents SDK in 2026: A Hands-On Walkthrough

Step-by-step build of a working agent with the OpenAI Agents SDK — Agent class, tools, handoffs, tracing — plus an eval pipeline that catches regressions before merge.

Agentic AI

Multi-Agent Handoffs with the OpenAI Agents SDK: The Pattern That Actually Scales (2026)

Handoffs done right — when one agent should hand control to another, how to preserve context, and how to evaluate the handoff decision itself.