What is session persistence for browser agents?

Session persistence is the umbrella term for how a browser agent carries authenticated state from one run to the next: cookies, localStorage, sessionStorage, IndexedDB, cache. The right implementation ranges from hand-pickled storage-state files (cheap, brittle) to fully-managed browser profiles (the Notte primitive). The point of all of them is the same — don't re-authenticate every five minutes.
What is session persistence for browser agents?
A fresh browser is a fresh visitor. No cookies, no localStorage, no remembered device. That's exactly what you don't want when an agent has just spent thirty seconds clicking through a login flow with 2FA — and is about to throw all of that away because the next run starts from zero. Session persistence is the bundle of techniques that closes the loop: save what the browser learned, replay it on the next run, skip the parts that don't need to happen twice.
What's actually inside a "session"
When agent stacks talk about persisting a session, they usually mean keeping some subset of these:
- Cookies (the most-cited; not the most-used in modern apps)
- localStorage (where most SPAs actually keep auth tokens)
- sessionStorage (per-tab, often holds short-lived auth state)
- IndexedDB (offline app data, sometimes credentials)
- Cache (HTTP cache + Service Worker caches; matters for app shell)
- Cookie partitioning state (per-site partitioned storage in modern browsers)
A persistence story that only saves cookies is a 2014 persistence story. A modern app like Google or a banking dashboard keeps half its login state in localStorage and IndexedDB. If you're not capturing those, the agent re-authenticates on the next run no matter what your "save cookies" code looks like.
Implementation patterns, weakest to strongest
Three layers, in increasing order of how much they actually preserve:
1. Hand-pickled cookies
session.cookies() → JSON file → load on next run. Cheap, captures roughly nothing of what modern apps need. The legacy approach; mostly useful for historical compatibility.
2. Playwright-style storage state
Frameworks like Playwright expose a storage_state snapshot that captures cookies + localStorage + sessionStorage in a structured JSON file. Better — covers most modern auth flows. Limitations: no IndexedDB, no cache, fingerprint resets on each run, you manage the file lifecycle yourself.
3. Managed browser profiles (Notte)
A full snapshot of the browser state — cookies, all storage classes, cache, even the rendered fingerprint surface — managed by the platform with explicit lifecycle controls. See what is a browser profile for AI agents for the SDK shape: client.profiles.create(name=...) plus client.Session(profile={"id": ..., "persist": True/False}). Strongest, simplest API surface, supports parallel reads from the same profile.
How session persistence relates to identity, vault, and profile
Easy to conflate; they solve different problems and should be combined deliberately:
- Session persistence is what state survives across runs.
- Credential vaulting is where the password lives so the LLM doesn't see it.
- Digital identity is who the agent shows up as — name, email, phone, fingerprint.
- Browser profile is the Notte primitive that implements session persistence, attached to a session at start.
You'd use a profile when you need cookies + storage + cache to survive across runs. You'd use an identity when you need a coherent name + email + phone the agent can act through. You'd use both together when an agent acts as a stable user against a site whose login is too custom to automate fresh.
Common pitfalls
- Persisting only cookies on a modern SPA. The auth lives in localStorage. The agent will re-login every run no matter how carefully you saved cookies.
- Reusing the same persistent state across users in a multi-tenant product. Now every agent run looks like the same human. Per-user isolation requires per-user persistence.
- Letting persistence drift across runs. If a session writes back state on every run, eventually the storage holds something the next run doesn't expect. The Notte profile model handles this by separating bootstrap (
persist=True) from reuse (persist=False, read-only); roll-your-own pickling rarely does.
Key takeaways
- Session persistence is what carries authenticated state across runs: cookies, localStorage, sessionStorage, IndexedDB, cache.
- "Save cookies" is the weakest possible interpretation; modern apps keep most auth state outside cookies.
- The three implementation patterns are hand-pickled cookies (legacy), Playwright
storage_state(most agent stacks), and managed browser profiles (Notte's primitive — strongest and simplest API). - Combine with identity for who and vault for secret — persistence handles what survives.