Skip to main content
Version: v2

Creating Sessions

When building automation workflows, you often need to maintain browser state across multiple connections such as keeping a user logged in, preserving shopping cart contents, or maintaining form data between script runs. Browserless provides two distinct approaches for creating persistent browser sessions that survive disconnections and allow you to resume automation from where you left off.

Session Management Approaches

Browserless offers two methods for managing persistent browser sessions:

1. Browser Sessions - Use the Browserless.reconnect CDP command to maintain state between connections. This approach works with all automation libraries and automatically manages session lifecycle through browser process persistence.

2. Session API - Provides explicit programmatic control over session creation and deletion through dedicated REST endpoints. This approach is designed for advanced use cases requiring precise lifecycle management or integration with larger automation platforms.

Which approach to use

Use Browser Sessions When:

  • Working with existing automation scripts
  • Need simple session persistence with minimal setup
  • Want maximum compatibility across automation libraries
  • Session lifetime is managed by your application logic
  • You prefer CDP-based session management

Use Session API When:

  • Needs a dedicated user data directory per session, persisting cache, cookies, localStorage, and session data for multiple days

  • Need explicit session lifecycle control through HTTP endpoints

  • Building advanced session management workflows

  • Want programmatic session creation/deletion capabilities

  • Need session monitoring and metadata access

  • Integrating with larger automation platforms or microservices

Pseudocode workflow diagram

Sessions workflows

Browser Sessions

The standard approach uses the Browserless.reconnect CDP command to generate a browserWSEndpoint to reuse later on, which keeps the browsers alive after disconnection for a specified timeout duration.

How Reconnection Works

When you use the Browserless.reconnect command, Browserless:

  1. Keeps the browser alive for the specified reconnection timeout duration after you disconnect
  2. Maintains browser state including cookies, localStorage, sessionStorage, and cache
  3. Allows reconnection to the same browser instance within the reconnection timeout window
  4. Automatically cleans up the browser instance after the reconnection timeout expires

Important: The browser session itself can run for the full session duration (15-60 minutes), but once you disconnect after using reconnect, you have a limited time window to reconnect to that specific browser instance. It's critical to note that the browser will be closed down if the browser.close() method is used, so you'll need to use the browser.disconnect() method so that the browser is kept alive for reconnection.

Browser Sessions Reconnection TTL Limitations by Plan

What is Reconnection TTL?

Reconnection TTL (Time-To-Live) is the maximum duration that a browser instance remains alive and available for reconnection after you disconnect from it using Browserless.reconnect. This is a reconnection window, not your overall session timeout.

Key distinctions:

  • Reconnection TTL: How long the browser waits for you to reconnect after using Browserless.reconnect and disconnecting (10 seconds to 5 minutes depending on plan)
  • Overall Session Timeout: Total time your browser session can run continuously (15-60 minutes depending on plan)
  • Reconnection Window: The specific time period during which you can reconnect to the same browser instance

If you don't reconnect within the TTL window, that specific browser instance closes, but you can always start a new session.

The reconnection Time-To-Live duration is 30 seconds (30,000ms) by default, but can be increased depending on your plan type.

PlanMaximum Reconnection TTLOverall Session Timeout
Free10 seconds (10,000ms)60 seconds
Prototyping/Starter1 minute (60,000ms)15-30 minutes
Scale5 minutes (300,000ms)60 minutes

Creating a Session

import puppeteer from "puppeteer-core";

// Connect to browser with your API token
const browser = await puppeteer.connect({
browserWSEndpoint: "wss://production-sfo.browserless.io?token=YOUR_API_TOKEN",
});

const page = await browser.newPage();
const cdp = await page.createCDPSession(); // Create CDP session for reconnection
await page.goto("https://example.com");

// Set up session state that will persist across reconnections
await page.evaluate(() => {
localStorage.setItem("myData", "persistent-value");
});

// Enable reconnection with 60 second timeout (must be within plan limits)
const { error, browserWSEndpoint } = await cdp.send("Browserless.reconnect", {
timeout: 60000, // Browser stays alive for 60 seconds after disconnect
});

if (error) throw error;
console.log("Reconnection endpoint:", browserWSEndpoint);

// Use disconnect() instead of close() to keep browser alive for reconnection
await browser.disconnect(); // Browser remains alive for 60 seconds

Session Configuration

You can combine reconnection timeouts with other browser options for advanced configuration:

// Configure browser with launch parameters that will persist across reconnections
const queryParams = new URLSearchParams({
token: "YOUR_API_TOKEN",
stealth: true, // Enable stealth mode for bot detection bypass
proxy: "residential", // Use residential proxy
headless: false, // Run in headed mode for debugging
});

const browser = await puppeteer.connect({
browserWSEndpoint: `wss://production-sfo.browserless.io?${queryParams.toString()}`,
});

const page = await browser.newPage();
const cdp = await page.createCDPSession(); // Create CDP session for reconnection

// Enable reconnection with all launch options preserved
const { error, browserWSEndpoint } = await cdp.send("Browserless.reconnect", {
timeout: 60000, // All configured options remain active after reconnection
});

Session API

For more control over session lifecycle, you can use the REST API to explicitly create and manage sessions through HTTP endpoints. This approach provides programmatic session management with advanced control over session configuration and monitoring.

Creating a Session via REST API

// Configure session with explicit timeout and browser options
const sessionConfig = {
ttl: 180000, // Session timeout: 3 minutes (180,000ms)
stealth: true, // Enable stealth mode for bot detection bypass
headless: false, // Run in headed mode for debugging
args: [
"--no-sandbox", // Required for containerized environments
"--disable-dev-shm-usage", // Prevent shared memory issues
"--disable-background-timer-throttling", // Maintain performance
],
};

// Create session via REST API
const response = await fetch(
"https://production-sfo.browserless.io/session?token=YOUR_API_TOKEN",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(sessionConfig),
},
);

// Handle session creation errors
if (!response.ok) {
throw new Error(
`Failed to create session: ${response.status} "${await response.text()}"`,
);
}

// Extract WebSocket connection URL for automation libraries
const session = await response.json();
console.log("Session created, browserWSEndpoint:", session.connect);

Session Configuration Options

ParameterTypeDefaultDescription
ttlnumber300000Time-to-live in milliseconds (max 30 minutes)
stealthbooleanfalseEnable stealth mode to avoid detection
headlessbooleantrueRun browser in headless mode
argsstring[][]Additional Chrome launch arguments
proxyobjectnullProxy configuration

Connecting to Session API

After creating a session with the Session API, use the returned connect URL to connect your automation library to the persistent session:

import puppeteer from "puppeteer-core";

// Use the WebSocket URL returned from session creation
const connect =
"wss://production-sfo.browserless.io/e/53...21/session/connect/b9..7b?token=25df...";

// Connect to the existing session
const browser = await puppeteer.connect({
browserWSEndpoint: connect,
});

const page = await browser.newPage();
await page.goto("https://example.com");
console.log(await page.url());

// Check if session state persists from previous connections
const foo = await page.evaluate(() => {
return window.localStorage.getItem("foo");
});
if (foo) {
console.log("LocalStorage foo exists:", foo); // State persisted
} else {
console.log("LocalStorage foo does not exist, this is the first run");
}

// Session state is maintained by the Session API across connections
await page.evaluate(() => {
localStorage.setItem("foo", "bar"); // This will persist for future connections
});

// Session remains active even after closing browser connection
await browser.close(); // Session continues running until TTL expires

Next Steps