Published
- 5 min read
Mastering Browser Sessions with browser-use for Reliable AI Automations

Why sessions matter (especially for AI agents)
If your automation opens a browser, logs in, scrapes data, and closes — great. But real-world AI agents don’t just run one task. They follow up, revisit, continue conversations, and act on prior context. That requires sessions: preserving cookies, local storage, tabs, and even the page you left open.
browser-use
has rapidly become the go-to toolkit for this kind of stateful automation, with 70k+ GitHub stars and ~8k forks as of September 2025—an impressive signal of community adoption. Even better, the project is under active development, with v0.7.9 released on Sept 19, 2025.
This guide is a hands-on walkthrough of browser sessions in browser-use
: how they work, how to persist them, and how to apply them to AI automation use cases like lead generation, price monitoring, and post-login workflows. We’ll also cover security, observability, and MCP integrations for multi-session orchestration.
The mental model: Browser
= a session
In today’s browser-use
API, Browser
is an alias for BrowserSession
—use whichever name feels more natural. Think of it as the living container for your cookies, storage, tabs, and pages.
Key session-related settings live on the Browser
:
keep_alive
: keep the browser running after an agent finishes.user_data_dir
+profile_directory
: reuse your real Chrome profile (bookmarks, extensions, and existing cookies).storage_state
: inject a cookies/localStorage snapshot to start authenticated.allowed_domains
: restrict navigation scope for safety.
Quickstart: a persistent session you can reuse
import asyncio
from browser_use import Agent, Browser, ChatOpenAI
async def main():
browser = Browser(keep_alive=True) # keep session alive between tasks
await browser.start()
agent = Agent(
task="Open DuckDuckGo and search for 'browser-use founders'",
browser=browser,
llm=ChatOpenAI(model="gpt-4.1-mini"),
)
await agent.run(max_steps=3)
# Chain a second task using the *same* session + tab context
agent.add_new_task("Return the title of the first result")
await agent.run()
# When you're done with the long-lived session:
await browser.kill()
asyncio.run(main())
The official docs describe chaining tasks on the same browser session and show how keep_alive=True
preserves session data across runs.
Option A: Reuse your real Chrome profile (instant auth)
If you’ve already logged into sites in your daily Chrome profile, point browser-use
at that profile. This preserves your existing cookies—no need to re-authenticate.
import asyncio
from browser_use import Agent, Browser, ChatOpenAI
async def main():
# macOS paths shown; see docs for Windows/Linux variants
browser = Browser(
executable_path="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
user_data_dir="~/Library/Application Support/Google/Chrome",
profile_directory="Default", # e.g., "Profile 1" for a secondary profile
keep_alive=True
)
agent = Agent(
task='Open https://duckduckgo.com and search "browser-use session persistence"',
browser=browser,
llm=ChatOpenAI(model="gpt-4.1-mini"),
)
await agent.run()
asyncio.run(main())
Option B: Bring your own storage_state
(portable logins)
Prefer a clean profile but want a saved login? Pass a Playwright storage state file (cookies + localStorage) to the browser:
import asyncio, json
from browser_use import Agent, Browser, ChatOpenAI
async def main():
# Assume you've created ./auth.json with Playwright or a prior run
with open("./auth.json", "r") as f:
storage = json.load(f)
browser = Browser(storage_state=storage, keep_alive=True)
await browser.start()
agent = Agent(
task="Open https://example.com/account and report the welcome text",
browser=browser,
llm=ChatOpenAI(model="gpt-4.1-mini"),
)
await agent.run()
await browser.kill()
asyncio.run(main())
The docs recommend storage_state
for login cookies where possible—cleaner than handing real passwords to the model.
Remote & cloud sessions (scalable fleets)
You can provision a cloud browser or connect to an existing CDP endpoint. This is powerful for running many long-lived sessions in parallel.
import asyncio
from browser_use import Agent, Browser, ChatOpenAI
from browser_use.browser import ProxySettings
async def main():
# EITHER: built-in cloud browser
browser = Browser(use_cloud=True, keep_alive=True)
# OR: third-party CDP (uncomment and configure)
# browser = Browser(
# cdp_url="http://remote-server:9222",
# proxy=ProxySettings(server="http://proxy:8080",
# username="user", password="pass"),
# keep_alive=True
# )
agent = Agent(task="Open example.com and extract the H1 text",
llm=ChatOpenAI(model="gpt-4.1-mini"),
browser=browser)
await agent.run()
asyncio.run(main())
Security essentials for long-lived sessions
- Constrain navigation with
allowed_domains=[...]
. - Prefer
storage_state
over raw credentials. - Beware of
disable_security=True
— not recommended.
Designing a Session Pool (multi-tenant or multi-workflow)
For AI automation backends, treat sessions as first-class resources. A simple in-memory pool looks like this:
import asyncio
from browser_use import Browser
class SessionPool:
def __init__(self):
self._by_tenant: dict[str, Browser] = {}
async def get_or_create(self, tenant_id: str) -> Browser:
if tenant_id not in self._by_tenant:
b = Browser(keep_alive=True)
await b.start()
self._by_tenant[tenant_id] = b
return self._by_tenant[tenant_id]
async def close(self, tenant_id: str):
b = self._by_tenant.pop(tenant_id, None)
if b:
await b.kill()
async def close_all(self):
for b in list(self._by_tenant.values()):
await b.kill()
self._by_tenant.clear()
This pattern lets you route tasks to the right long-lived session: perfect for CRM workflows, per-client scrapers, or customer-specific dashboards.
Chaining tasks conversationally
Agent.add_new_task()
lets you append follow-ups without tearing down the browser. It’s ideal for assistants that iterate step by step.
- Cookies persist
- LocalStorage persists
- Tabs persist
Observability: trace session timelines
For production systems, trace both agent reasoning and the browser session timeline. browser-use
integrates with Laminar, aligning each agent step with the session recording—crucial when debugging why a session lost auth or a selector failed.
MCP: Manage sessions from AI assistants
Running browser-use
as an MCP server exposes tools your AI assistant can call—including session management:
browser_list_sessions
browser_close_session
browser_close_all
Once you start uvx browser-use --mcp
, assistants like Claude Desktop can reuse or terminate sessions on demand.
Conclusion ✅
Browser sessions are the backbone of reliable AI automations. With browser-use
, you can:
- Persist context across multiple tasks
- Reuse Chrome profiles or portable states
- Securely scale with cloud sessions
- Trace and debug with observability tools
- Orchestrate workflows with session pools
If you’re building agents that need to remember and continue, sessions are not optional — they’re essential. 🚀