> ## Documentation Index
> Fetch the complete documentation index at: https://tbd-6fc993ce-hypeship-docker-sandboxes-integration.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Pre-configure pools of reserved browsers for immediate acquisition

Browser pools let you maintain a set of reserved, identical browsers ready for immediate use. Use them to set your preferred browser configuration in advance, allowing you to minimize browser start-up latency and scale your workloads in production.

## How browser pools work

Browser pools are a way to pre-configure a fixed set of browsers without being charged for them until they are used (i.e. `acquired`). All browsers in the pool share the same settings upon instantiation.

<Steps>
  <Step title="Declare a pool">
    First, declare a pool of browsers with your specified configuration. The pool takes time to fill (see [fill rate per minute](https://www.kernel.sh/docs/api-reference/browser-pools/create-a-browser-pool#body-fill-rate-per-minute)), so declare your pool outside your browser automation / agent runtime logic.

    <Info>
      Pool declarations should be decoupled from browser runtime logic for the best performance.
    </Info>
  </Step>

  <Step title="Acquire a browser">
    You can acquire a browser as soon as you've created a pool. The request returns immediately if a browser is available, or waits until one becomes available.

    The total number of browsers is fixed to the `size` specified upon browser pool creation. When you acquire a browser, the pool's available count is decremented by one. When you release a browser, the pool's available count is incremented by one.

    <Info>
      Put differently, the pool does not top up when you acquire a browser: browsers are "borrowed" from the pool and must be returned when you're done with them, either by [releasing them](#release-a-browser) or allowing them to [timeout](#timeout-behavior).
    </Info>
  </Step>

  <Step title="Release a browser">
    When you're done with a browser, release it back to the pool. this step is important; otherwise, the browser will continue to be in an `acquired` state until it times out.

    <Info>
      Failing to release browsers may result in unexpected latency when acquiring future browsers.
    </Info>
  </Step>
</Steps>

## Create a pool of reserved browsers

Create a browser pool with a specified size and configuration. All browsers in the pool share the same settings.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  import Kernel from '@onkernel/sdk';

  const kernel = new Kernel();

  const pool = await kernel.browserPools.create({
    name: "my-pool",
    size: 10,
    stealth: true,
    headless: false,
    timeout_seconds: 600,
    viewport: {
      width: 1280,
      height: 800
    }
  });

  console.log(pool.id);
  ```

  ```python Python theme={null}
  from kernel import Kernel

  kernel = Kernel()

  pool = kernel.browser_pools.create(
      name="my-pool",
      size=10,
      stealth=True,
      headless=False,
      timeout_seconds=600,
      viewport={
          "width": 1280,
          "height": 800
      }
  )

  print(pool.id)
  ```
</CodeGroup>

### Pool configuration options

Pools can be pre-configured with options like custom extensions, supported viewports, residential proxies, profiles, and more. See the [API reference](https://kernel.sh/docs/api-reference/browser-pools/create-a-browser-pool) for more details.

## Acquire a browser

Acquire a browser from the pool. The request returns immediately if a browser is available, or waits until one becomes available. The `acquire_timeout_seconds` parameter controls how long to wait; it defaults to the calculated time it would take to fill the pool at the pool's configured [fill rate](https://kernel.sh/docs/api-reference/browser-pools/create-a-browser-pool#body-fill-rate-per-minute).

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const browser = await kernel.browserPools.acquire("my-pool", {
    acquire_timeout_seconds: 30,
  });

  console.log(browser.session_id);
  console.log(browser.cdp_ws_url);
  ```

  ```python Python theme={null}
  browser = kernel.browser_pools.acquire(
      "my-pool",
      acquire_timeout_seconds=30,
  )

  print(browser.session_id)
  print(browser.cdp_ws_url)
  ```
</CodeGroup>

The acquired browser includes all the same properties as a regular browser session, including `cdp_ws_url` for CDP connections and `browser_live_view_url` for live viewing.

### Timeout behavior

Browsers remain in the pool indefinitely until acquired. Once acquired, the pool's `timeout_seconds` applies just like a [regular browser timeout](/browsers/termination#automatic-deletion-via-timeout)—if the browser is idle (no CDP or live view connection) for longer than the timeout, it is destroyed and **not** returned to the pool. The pool will automatically create a replacement browser at the pool's configured [fill rate](https://kernel.sh/docs/api-reference/browser-pools/create-a-browser-pool#body-fill-rate-per-minute).

## Release a browser

When you're done with a browser, release it back to the pool. By default, the browser instance is reused. Set `reuse: false` to destroy it and create a fresh one.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  await kernel.browserPools.release("my-pool", {
    session_id: browser.session_id,
    reuse: true,
  });
  ```

  ```python Python theme={null}
  kernel.browser_pools.release(
      "my-pool",
      session_id=browser.session_id,
      reuse=True,
  )
  ```
</CodeGroup>

## Update a pool

Update the pool configuration. By default, all idle browsers are discarded and rebuilt with the new configuration.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const updatedPool = await kernel.browserPools.update("my-pool", {
    size: 20,
    stealth: true,
  });
  ```

  ```python Python theme={null}
  updated_pool = kernel.browser_pools.update(
      "my-pool",
      size=20,
      stealth=True,
  )
  ```
</CodeGroup>

<Info>
  The `size` parameter is always required when updating a pool, even if you only want to change other settings.
</Info>

By default, updating a pool discards all idle browsers and rebuilds them with the new configuration. Set `discard_all_idle: false` to keep existing idle browsers and only apply the new configuration to newly created browsers.

## Flush idle browsers

Destroy all idle browsers in the pool. Acquired browsers are not affected. The pool will automatically refill with the pool's specified configuration.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  await kernel.browserPools.flush("my-pool");
  ```

  ```python Python theme={null}
  kernel.browser_pools.flush("my-pool")
  ```
</CodeGroup>

## Get pool details

Retrieve the current status and configuration of a pool.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const pool = await kernel.browserPools.retrieve("my-pool");

  console.log(pool.available_count);
  console.log(pool.acquired_count);
  ```

  ```python Python theme={null}
  pool = kernel.browser_pools.retrieve("my-pool")

  print(pool.available_count)
  print(pool.acquired_count)
  ```
</CodeGroup>

## List pools

List all browser pools in your organization.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const pools = await kernel.browserPools.list();

  for (const pool of pools) {
    console.log(pool.name, pool.available_count);
  }
  ```

  ```python Python theme={null}
  pools = kernel.browser_pools.list()

  for pool in pools:
      print(pool.name, pool.available_count)
  ```
</CodeGroup>

## Delete a pool

Delete a browser pool and all browsers in it. By default, deletion is blocked if browsers are currently acquired. Use `force: true` to terminate acquired browsers and force deletion.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  // Delete a pool (fails if browsers are acquired)
  await kernel.browserPools.delete("my-pool");

  // Force delete even if browsers are acquired
  await kernel.browserPools.delete("my-pool", { force: true });
  ```

  ```python Python theme={null}
  # Delete a pool (fails if browsers are acquired)
  kernel.browser_pools.delete("my-pool")

  # Force delete even if browsers are acquired
  kernel.browser_pools.delete("my-pool", force=True)
  ```
</CodeGroup>

## Full example

This example assumes you've already created a pool named "my-pool". In practice, you'd create pools once (via the SDK, CLI, or dashboard) and then acquire from them repeatedly.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  import Kernel from '@onkernel/sdk';
  import { chromium } from 'playwright';

  const kernel = new Kernel();

  // Acquire a browser from an existing pool
  const kernelBrowser = await kernel.browserPools.acquire("my-pool", {});

  try {
    // Connect via CDP
    const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url);
    const context = browser.contexts()[0];
    const page = context.pages()[0];

    await page.goto('https://example.com');
    const title = await page.title();
    console.log(title);
  } finally {
    // Release back to pool for reuse
    await kernel.browserPools.release("my-pool", {
      session_id: kernelBrowser.session_id,
    });
  }
  ```

  ```python Python theme={null}
  import asyncio
  from kernel import Kernel
  from playwright.async_api import async_playwright

  kernel = Kernel()

  async def main():
      # Acquire a browser from an existing pool
      kernel_browser = kernel.browser_pools.acquire("my-pool")

      async with async_playwright() as playwright:
          try:
              # Connect via CDP
              browser = await playwright.chromium.connect_over_cdp(kernel_browser.cdp_ws_url)
              context = browser.contexts[0]
              page = context.pages[0]

              await page.goto('https://example.com')
              title = await page.title()
              print(title)
          finally:
              # Release back to pool for reuse
              kernel.browser_pools.release(
                  "my-pool",
                  session_id=kernel_browser.session_id,
              )

  asyncio.run(main())
  ```
</CodeGroup>

## API reference

For more details on all available endpoints and parameters, see the [Browser Pools API reference](https://kernel.sh/docs/api-reference/browser-pools/list-browser-pools).
