We use cookies to enhance user experience, personalize content, and analyze traffic. Cookie Policy

← Back to all articles

Browser Use Agent Proxy Setup: Residential and ISP

Set up a proxy for a Browser Use agent: ProxySettings code, residential vs ISP IPs, sticky sessions, auth, and fixes for 407 errors and timeouts.

by Unknown Proxies

13 min read

September 30, 2026

Browser Use Agent Proxy Setup: Residential and ISP

A Browser Use agent drives a real Chromium browser, so the proxy has to be attached to that browser, not to your Python process. In Browser Use 0.13, you pass a ProxySettings object to Browser(proxy=...). Browser Use turns server into Chromium's --proxy-server launch flag and answers the proxy's authentication challenge with your username and password over the Chrome DevTools Protocol.

The harder decision is which IP the agent should sit behind. An agent that logs in, fills forms, or works through a multi-page flow needs one stable identity for the whole run: a sticky residential session or a dedicated ISP proxy. Per-request rotation, the default in many scraping setups, splits a single page load across several exit IPs and tends to break exactly the sessions an agent depends on.

This guide covers the setup code, how to choose residential or ISP proxies for browser use agent workloads, how to run several agents in parallel without mixing identities, and how to debug the failures that show up most often. The examples were checked against browser-use 0.13.10.

Browser Use agent architecture showing Chromium traffic routed through a proxy while LLM API calls go directly to the model provider

Browser Use Agent Proxy: Quick Setup

Install the library and its Chromium build first:

uv add browser-use
uv run browser-use install

browser-use install wraps playwright install chromium, so it only needs to run once per machine or container image.

Then create a Browser with a proxy and hand it to the agent:

import asyncio
import os

from browser_use import Agent, Browser, ChatOpenAI
from browser_use.browser import ProxySettings


async def main():
    browser = Browser(
        proxy=ProxySettings(
            server="http://proxy.example.com:8080",
            username=os.environ["PROXY_USERNAME"],
            password=os.environ["PROXY_PASSWORD"],
            bypass="localhost,127.0.0.1",
        ),
    )

    agent = Agent(
        task="Open https://api.ipify.org and report the IP address shown on the page",
        llm=ChatOpenAI(model="gpt-5.5"),
        browser=browser,
    )
    history = await agent.run(max_steps=10)
    print(history.final_result())


if __name__ == "__main__":
    asyncio.run(main())

ChatOpenAI reads OPENAI_API_KEY from the environment. Any chat model Browser Use supports works here; the proxy setup does not depend on the LLM.

What each field does:

Field Becomes Notes
server --proxy-server=... Include the scheme: http://host:port or socks5://host:port
username / password CDP Fetch.authRequired responses Only proxy challenges are answered; site logins are left alone
bypass --proxy-bypass-list=... Comma-separated hosts that should connect directly

If the final result prints the proxy's exit IP rather than your own, the browser is routed correctly. Run this check before giving the agent a real task. Debugging a bad proxy through an LLM loop costs tokens and produces confusing step logs, because the agent will try to "fix" a connection error by clicking around.

Test the proxy outside the agent first:

curl -x "http://$PROXY_USERNAME:$PROXY_PASSWORD@proxy.example.com:8080" https://api.ipify.org

If curl fails, Browser Use will fail too. If your provider hands out lines like host:port:username:password, split them into server, username, and password. The proxy converter can reformat a whole list when a tool expects a different layout.

What Goes Through the Proxy and What Does Not

A browser use agent has two separate network paths, and only one of them uses ProxySettings:

The browser's CDP connection is local as well. When Browser Use launches Chromium on your machine it talks to it over localhost. If you do export HTTP_PROXY or HTTPS_PROXY, also set NO_PROXY=localhost,127.0.0.1 so that local DevTools traffic is not sent to the proxy.

The common mistake is exporting HTTPS_PROXY to "make the agent use the proxy." The OpenAI and Anthropic Python SDKs are built on httpx, which honors HTTP_PROXY, HTTPS_PROXY, and ALL_PROXY by default. With a residential proxy in those variables, every model call, screenshots included, travels through a plan billed per GB. Set the proxy on the browser and keep the process environment clean unless you have a specific reason to route API traffic.

Residential vs ISP Proxies for a Browser Use Agent

Both proxy types work with Browser Use. The choice depends on whether the agent needs one long-lived identity or many short independent ones.

Agent workload Better fit Session pattern
Operating accounts you own (dashboards, seller portals, CRMs) ISP Same IP and same browser profile every run
Multi-step forms, checkout tests, onboarding flows ISP or sticky residential One IP for the entire run
Research across many public sites Sticky residential New sticky session per task
Localized QA by country or state Residential Sticky session in the target location
Thousands of independent page fetches Probably not an agent job Use an HTTP client or Playwright with rotating contexts

ISP proxies are static IPs announced by internet service providers and hosted on fast infrastructure. You keep the same IP for the life of the plan, which is what an agent operating a logged-in account needs: the site sees the same address, the same cookies, and the same browser profile day after day. They are also priced per IP rather than per GB, which matters for agents because full browser sessions are bandwidth-heavy. For the deeper tradeoffs, see ISP proxies vs residential.

Residential proxies give you consumer IP space and broad geographic coverage. Use them in sticky mode for agents. Unknown Proxies sticky residential sessions keep the same exit IP for up to 2 hours, which covers most agent runs with room to spare. Rotating residential endpoints change the IP on every request, which suits stateless HTTP scraping and almost never suits an agent.

Why rotating proxies break agents

A browser does not make one request per page. Loading a typical page opens many connections for the document, scripts, API calls, and assets. With per-request rotation, the HTML can arrive from one IP, the login POST from a second, and the session check from a third.

Sites that bind a session to an IP or a risk score react predictably: logouts, repeated challenges, "session expired" banners, or a 403 Forbidden on the step that matters. The agent does not know the network changed under it. It sees a login page again, tries to log in again, and burns steps in a loop. The sticky vs rotating proxies guide covers the session mechanics in more detail.

Comparison of one agent run on a sticky proxy keeping a single exit IP versus a rotating proxy changing IPs between steps and breaking the session

One Identity per Agent: Sticky Sessions and Profiles

The rule that prevents most problems: one agent, one Browser, one proxy identity, one profile directory.

By default Browser Use creates a fresh temporary profile for each browser session. That is right for independent tasks, since nothing leaks between runs. For an account the agent should stay logged into, point user_data_dir at a persistent directory and always pair that directory with the same ISP IP. Cookies issued to one IP and replayed from another look like a stolen session to many risk systems.

Here is a pattern for running several agents in parallel, each pinned to its own proxy line and profile:

import asyncio
from pathlib import Path

from browser_use import Agent, Browser, ChatOpenAI
from browser_use.browser import ProxySettings

# One proxy per line: host:port:username:password
PROXY_LINES = [
    line.strip()
    for line in Path("proxies.txt").read_text().splitlines()
    if line.strip()
]

TASKS = [
    "Log in to the vendor portal and download this month's invoice list as CSV",
    "Check the order status page and report any orders marked delayed",
    "Open the pricing page and report the listed price for the Pro plan",
]


def make_browser(proxy_line: str, profile: str) -> Browser:
    host, port, username, password = proxy_line.split(":", 3)
    return Browser(
        proxy=ProxySettings(
            server=f"http://{host}:{port}",
            username=username,
            password=password,
        ),
        user_data_dir=f"~/.browser-use-profiles/{profile}",
        headless=True,
    )


async def run_agent(task: str, proxy_line: str, profile: str, limit: asyncio.Semaphore):
    async with limit:
        agent = Agent(
            task=task,
            llm=ChatOpenAI(model="gpt-5.5"),
            browser=make_browser(proxy_line, profile),
        )
        history = await agent.run(max_steps=30)
        return profile, history.final_result()


async def main():
    limit = asyncio.Semaphore(3)
    jobs = [
        run_agent(task, proxy_line, f"agent-{i}", limit)
        for i, (task, proxy_line) in enumerate(zip(TASKS, PROXY_LINES))
    ]
    for profile, result in await asyncio.gather(*jobs):
        print(profile, result)


asyncio.run(main())

A few details that matter in production:

Authentication and Protocol Details

HTTP proxies with a username and password are the default path. When credentials are set, Browser Use enables the CDP Fetch domain and replies to authRequired events whose source is the proxy. You do not need a browser extension or a login dialog handler.

SOCKS5 with credentials does not work in Chromium. The Chromium proxy documentation states that no authentication methods are supported for SOCKSv5. Browser Use can pass socks5://host:port to Chromium, but the username and password will never be used. Use your provider's HTTP endpoint, or an unauthenticated SOCKS5 endpoint with IP allowlisting. The SOCKS5 vs HTTP proxy guide explains the protocol differences.

IP allowlist authentication means leaving username and password out. The machine running Chromium must be on the allowlist, which is easy to forget in CI runners and autoscaled containers whose egress IP changes between deploys.

Credentials belong in environment variables or a secrets manager. Pass them as separate fields rather than embedding user:pass@ in the server URL, because the auth handler reads the dedicated fields.

Browser Use Cloud vs Bringing Your Own Proxy

ProxySettings configures the Chromium that Browser Use launches locally. Browser Use Cloud is a different setup: Browser(use_cloud=True) runs the browser remotely, and cloud_proxy_country_code="de" selects the cloud's built-in proxy country. Per the library source, the cloud applies a US proxy when you pass nothing, and cloud_proxy_country_code=None turns the proxy off.

If the cloud's built-in proxy covers your needs, you do not need a separate provider. Bring your own proxies when you run Chromium yourself (locally, in Docker, on your own servers), when an account must stay pinned to one static IP across months, when you need state or city targeting, or when you need ISP IPs specifically.

One trap: if you attach Browser Use to an already-running Chrome through cdp_url, launch flags such as --proxy-server are not applied, because Browser Use did not start that browser. Launch that Chrome with the proxy flag yourself, or let Browser Use launch it.

Browser Use CAPTCHA Behavior Behind Your Own Proxy

Browser Use 0.13 has a captcha_solver setting on Browser, and it defaults to True. It is not a local solver. It is a watchdog that listens for CAPTCHA events emitted by Browser Use's cloud browser infrastructure and pauses the agent's steps while the cloud handles the challenge. A local Chromium behind your own proxy never emits those events, so the setting has no effect there. When a CAPTCHA appears, the agent sees it as part of the page and may stall, retry, or give up.

What you control locally is how often challenges appear. On most sites that comes down to three signals:

One sticky residential session or ISP IP per agent, plus slower pacing such as Browser(wait_between_actions=1.0) and lower concurrency per IP, reduces false-positive challenges on sites you are allowed to automate. It does not guarantee a challenge-free run. If a site challenges every run, treat that as the site's decision about automated access: use its official API, ask for permission, or drop the target rather than trying to push through.

Bandwidth: Agents Are Expensive Browsers

An agent loads full pages at every step: images, fonts, scripts, and tracking calls included. The HTTP Archive measured the median desktop page at 2,652 KB in 2024. A 25-step task that visits 10 pages can move 25 to 40 MB through the proxy once redirects, API calls, and repeat loads are counted. At 1,000 runs a day, that is 25 GB or more.

That math is why the proxy type affects cost as much as success rate:

Debugging a Browser Use Agent Proxy

Step-by-step debugging ladder for a Browser Use agent proxy, from a curl test to an IP check task to the real target

Test one layer at a time and do not move up until the current layer works:

  1. curl through the proxy to confirm host, port, scheme, and credentials.
  2. Run the IP-check task from the quick setup to confirm Chromium is routed.
  3. Run headed with headless=False and watch the first real page load.
  4. Point the agent at the real target with a low max_steps.
Symptom Likely cause First fix
ERR_PROXY_CONNECTION_FAILED or ERR_TUNNEL_CONNECTION_FAILED Wrong host, port, or scheme, or the proxy is unreachable Repeat the curl test; see ERR_PROXY_CONNECTION_FAILED
407 or repeated auth failures Wrong credentials Re-check username and password; see 407 Proxy Authentication Required
ERR_SOCKS_CONNECTION_FAILED with credentials set SOCKS5 endpoint requires auth that Chromium cannot send Switch to the HTTP endpoint or IP allowlisting
IP check shows your real IP Proxy not applied: cdp_url attach or proxy passed to the wrong object Pass proxy= to the Browser the agent actually uses
IP check shows a US or cloud IP use_cloud=True: ProxySettings is not used Set cloud_proxy_country_code or run Chromium locally
Agent loops on login or "session expired" IP changing mid-run Use a sticky session or ISP IP for the whole run
403, 429, or challenge pages Proxy works; the site is rejecting the traffic pattern Reduce concurrency and step pace; see 429 Too Many Requests
Local app or internal tool unreachable Localhost traffic is being proxied Add hosts to bypass
Navigation times out, or the agent acts on half-loaded pages Slow proxy route or heavy page hitting the 30-second navigation limit Raise the timeouts below after confirming the proxy responds quickly

A 403 or 429 is useful information: the request reached the site. At that point, rotating IPs harder usually makes things worse. Slow the agent down, lower concurrency per IP, and check whether the site expects this kind of automated access at all.

Fixing timeouts behind a proxy

Residential routes add latency, and heavy pages take longer to settle. Browser Use 0.13 has two tunable limits worth knowing, and one that is not tunable:

export TIMEOUT_NavigateToUrlEvent=60

With the same imports as the quick setup:

browser = Browser(
    proxy=ProxySettings(
        server="http://proxy.example.com:8080",
        username=os.environ["PROXY_USERNAME"],
        password=os.environ["PROXY_PASSWORD"],
    ),
)

agent = Agent(
    task="Open https://example.com and summarize the page",
    llm=ChatOpenAI(model="gpt-5.5"),
    browser=browser,
    step_timeout=300,
)

Raise these only after the curl test returns in a second or two. If the proxy itself takes 10 seconds to answer, a longer timeout hides a bad route instead of fixing it. Switch to a closer location or an ISP IP instead.

Use Agents Within Site Rules

Agents act on websites with your credentials and your intent, so the usual boundaries apply with more force. Automate accounts you own or are authorized to operate, follow each site's terms and rate limits, and do not use proxies to get around bans or access controls. A proxy gives the agent a stable, well-located network identity; it does not make unauthorized automation acceptable. For scraping-specific boundaries, see is data scraping legal.

FAQ

How do I add a proxy to a Browser Use agent?

Create Browser(proxy=ProxySettings(server="http://host:port", username=..., password=...)) and pass it to Agent(browser=...). Import ProxySettings from browser_use.browser.

Does Browser Use support SOCKS5 proxies?

Yes, as socks5://host:port, but Chromium does not support SOCKS5 username and password authentication. Use an HTTP endpoint for authenticated proxies, or IP allowlisting for SOCKS5.

Should a browser use agent use rotating proxies?

Rarely. Per-request rotation changes the exit IP between steps and even between requests within one page load, which breaks logins and multi-step flows. Use a sticky residential session per task or a static ISP IP.

Are residential or ISP proxies better for Browser Use?

ISP proxies fit agents that operate the same accounts repeatedly, because the IP never changes and pricing is per IP. Residential proxies fit agents that need many locations or fresh identities per task, used in sticky mode.

Does the proxy slow the agent down?

Somewhat, but the LLM call at each step usually dominates run time. ISP proxies add the least latency. On slower residential routes, raise TIMEOUT_NavigateToUrlEvent (30 seconds by default) and step_timeout on Agent (180 seconds by default) instead of relying on local-network defaults.

Does Browser Use solve CAPTCHAs when you run your own proxy?

No. The captcha_solver setting only reacts to events from Browser Use cloud browsers. With a local Chromium behind your own proxy, you can lower how often challenges appear with one stable IP per agent and slower pacing, but nothing solves them for you.

Final Thoughts

A browser use agent needs its proxy set on the browser, not the process: Browser(proxy=ProxySettings(...)), with HTTP credentials in separate fields and a quick IP check before any real task. Give each agent one identity for the full run, pair persistent profiles with fixed IPs, and keep LLM traffic off your proxy plan.

For agents that manage the same accounts every day, compare ISP proxy plans. For agents that need geographic coverage or fresh sticky sessions per task, start with residential proxies. If you also run conventional browser automation next to your agents, the Playwright proxy guide covers context-level rotation.

Technical references: Browser Use browser parameters, Browser Use on GitHub, Chromium proxy support, and the Chrome DevTools Protocol Fetch domain.

About the Author

Unknown Proxies

Proxy Infrastructure Team

Stay Unknown

High-performance dedicated proxies optimized for speed and reliability. Get uncompromising quality, 99.9% uptime, and unmatched support. Stay Unknown.

Explore Plans