Skip to main content
Browserbase Cache is a managed, server-side caching layer built into the Stagehand API. When you run Stagehand with env: "BROWSERBASE", every act(), extract(), and observe() call is automatically cached on Browserbase’s servers. Repeated calls with the same inputs return instantly without consuming any LLM tokens. You don’t need to configure anything to start benefiting. Server caching can be used independently or together with Local Caching.

Using the Cache

Caching is on by default. Run your automation as normal and repeated actions are served from the cache:
The cache key is a combination of the instruction, page content, and options you pass. On a cache hit, the response is returned directly from the server with no LLM inference and no token cost. Check out the Browserbase blog for more details on how it works under the hood.

Checking Cache Status

act() returns a cacheStatus field you can use to verify whether a result was served from cache:
On a miss, the result also tells you why the cache missed when the server reports a reason, via the cacheMissReason field:
The field is available on act(), extract(), and observe() results. Possible reasons:
Cache status for your sessions in the Browserbase dashboard is coming soon.

Best Practices

Tune the cache threshold

Before a cached result is served, the same action must have been seen a certain number of times — the validation threshold. This protects you from replaying a one-off result on a page that isn’t actually deterministic. Browserbase manages the default for you, but you can override it per action with serverCacheThreshold:
The value persists on the cache entry, so later calls that omit serverCacheThreshold keep honoring it; passing a new value updates it. Use a low threshold (like 1) for flows you know are stable to start hitting the cache immediately, or a higher one when you want more repeated observations before trusting the cached result. It must be a non-negative integer, and it also works on extract() and observe().

Scope actions with a selector

When targeting a specific part of a page, pass a selector to scope the accessibility tree snapshot to that container. This reduces token costs, speeds up inference, and — crucially for caching — means that changes outside the container don’t affect the cache key. On content-heavy pages (search results, dashboards, feeds), scoping is often the difference between a stable cache key and a new miss on every visit.

Use variables for dynamic values

Using variables in act() lets you generalize a single cache entry across many different values. The cache key is built from the variable keys, not the values — so { email: "alice@example.com" } and { email: "bob@example.com" } share the same entry. Without variables you’d accumulate a separate cache miss for every unique email address you type. With variables you prime the cache once and hit it forever.

Stabilize the environment

Small differences in runtime state produce different accessibility trees and therefore different cache keys. Keep your environment as deterministic as possible:
  • Fixed viewport sizeawait page.setViewportSize({ width: 1280, height: 720 })
  • Consistent user agent and locale — set these in your browser launch options if your stack supports it

Keep prompts deterministic

The exact instruction is part of the cache key. Even minor wording changes — synonyms, extra adjectives, punctuation — produce a new key and a cache miss.
  • Anchor instructions to visible UI labels: "click the Sign in button" not "click the button to log me in"
  • Keep instructions short and free of filler words
  • Avoid instructions that contain runtime-variable text inline — use variables instead

Limitations

  • The page URL factors in to the cache key. If the action is being made on a page with a dynamic URL, caching may not work as expected. We do filter out certain query parameters like referral trackers and analytics, but we don’t catch everything just yet.
  • If the page content or structure changes, the action won’t get a cache HIT and the LLM will be called. The subsequent actions will attempt to hit the resulting cache entry.
  • Page content changes aren’t always visual or apparent — dynamic IDs, rotating ad slots, or injected scripts can shift the DOM between loads even when the page looks identical. If an action keeps getting cache misses after repeated calls, it’s worth checking how consistent the DOM actually is across loads and scoping the action with a selector to the part of the page you care about, so DOM changes in irrelevant parts of the page don’t affect cache performance.

Disabling the Cache

Caching is on by default, but you can opt out at two levels. To disable caching for all requests made by an instance, pass serverCache: false to the constructor:
To override the instance setting for a single call, pass serverCache: false in the options: