TL;DR A browser running on your laptop keeps you logged in because it writes cookies and local storage to a profile on disk. Automation throws that profile away every run, so your script logs in again each time, which is slow and trips more anti-bot checks. To stay logged in, you persist the profile: save the auth state after the first login and load it before the next run. Browserbase Contexts do this for you, storing the full profile server-side and re-attaching it to any later session by ID.
You logged into a site in your automation, it worked, you shipped it. Then the next run opened a fresh browser and landed back on the login page. Nothing broke. The browser just did what a brand-new browser always does: it started with no memory of you.
This is the single most common wall people hit when they move an automation off their own machine. On your laptop the browser stays logged in for weeks. In a script, or on a server, or in a serverless function, every run starts clean. Here is why that happens and how to make login survive across runs.
Why does my automation lose its login every run?
Because a browser's memory of you lives in a user profile on disk, and automation usually starts without one.
When you log into a site, the server sends back a session cookie. Your browser stores that cookie, plus any local storage or IndexedDB the site writes, in a user data directory on disk. Next time you open the browser it reads that directory back, finds the cookie, and the site treats you as already signed in. That directory is the only reason your everyday browser remembers you.
Automation frameworks default to a throwaway profile. A fresh cloud session, a CI container, or a serverless invocation each start with an empty user data directory, so there is no cookie to read back and the site sends you to the login page. The login itself worked fine. The state it produced had nowhere durable to live.
What does it mean to persist a session?
Persisting a session means saving the login state produced by one run and loading it into the next, so the second run starts already authenticated.
There are two things worth persisting, and they are not the same. Cookies are the narrow answer: export the session cookie after login and re-add it before the next run. That works for simple cookie-based auth and is quick to wire up. The broader answer is the whole profile: cookies plus local storage, IndexedDB, service workers, and site preferences. Sites that keep auth state outside cookies need the whole profile, not just the cookie.
Both approaches share one shape. Save state at the end of a run, restore it at the start of the next, and check whether the restored state still logs you in before assuming it does.
How do you reuse just the cookies?
Save the site's cookies to durable storage after you log in, then add them back to the browser before the next run and skip the login flow if they still work.
This Playwright example logs in once, stores the cookies to a file, and on later runs restores them and checks a protected page before deciding whether to log in again.
This is fine when auth is a single cookie you control. It gets fragile fast when a site spreads state across local storage and IndexedDB, or rotates cookies on every request. At that point you want the whole profile, not one cookie.
How do you persist the whole profile with Contexts?
A Browserbase Context is a stored browser profile that lives server-side. You attach it to a session by ID, and it carries cookies, local storage, IndexedDB, service workers, and site preferences from one session to the next.
First, create a Context once and keep the ID it returns.
Then start a session with that Context ID and persist: true. The flag tells Browserbase to save any changes made during the session, so the login you do here is written back to the Context when the session closes.
Log in inside that first session, then let it close. Wait a few seconds for the Context to finish syncing, then start every future session with the same Context ID. Those sessions start already signed in. Set persist: false on later runs if you want to read the stored login without writing anything new back to it.
Contexts live indefinitely on Browserbase, so you create one, log in once, and reuse it for weeks. The difference from the cookie approach is scope. A Context restores the entire profile, so it covers sites whose auth state you could never capture from cookies alone.
Cookie reuse vs Contexts: which should you use?
What breaks, even with persistence?
Persisted state can still stop working, because the site controls whether a login stays valid. Persistence keeps your side of the login. The other side can still end it.
- Cookies expire. Sites set auth cookies to lapse after a period, so a saved login can go stale even though the Context is intact.
- Server-side logout. A password change or a "log out of all devices" action invalidates stored sessions from the server, and no amount of local state gets around it.
- Location checks. Some sites tie a session to where it was created. Keep a consistent geolocation across runs with a proxy so the restored login is not rejected.
- Simultaneous use. Running two sessions on the same Context at once can force a logout. Use one Context per site per login.
The practical takeaway is to never assume the restored login worked. Load the state, hit a protected page, and if you get redirected to login, re-authenticate and save the fresh state. Both patterns above already do this check, and it is the one habit that keeps a persistence setup from silently failing in production.
How do you take this to production?
The reason this problem feels sharp is that production is exactly where the throwaway profile bites. A serverless function or a scaled fleet of runs has no laptop-style profile to fall back on, so persistence has to be explicit.
This is the shape Contexts are built for. State lives server-side rather than in a file next to your code, it is encrypted at rest, and you attach it by ID from any session or serverless invocation. You get the reliability of a real browser profile without hosting the browser or the disk it writes to. Browserbase runs cloud browser sessions you connect to over CDP with Playwright, Puppeteer, or Stagehand, and Contexts, proxies, and login persistence are configuration on the session rather than infrastructure you maintain. The same setup also runs deterministically: pin the same Context, proxy, and inputs and you get a repeatable run rather than a fresh login every time.
To wire this up, create a Context, log in once with persist: true, and reuse the ID on every run. The full walkthrough is in the Contexts docs and the authentication guide.
