[cdpfleet](https://cdpfleet.com/) / Shared threads

Plans · shared threads

# Pooled browser-minutes for *bursty* work.

Each shared thread adds browser-minutes to one account pool and one more browser you can run at a time. Spend the pool on a few long sessions or many short ones — from $7.50 a month for 5 threads.

[Get started](https://cdpfleet.com/app)[See all prices](https://cdpfleet.com/pricing)

-   **$1.50–$4**per thread / month
-   **60–480**min per thread per day
-   **25%**of the pool per rolling hour
-   **5–1,000**threads

## One pool per account

A shared plan has two numbers: **threads** — how many browsers can run at once — and **browser-minutes per thread per day**. Every thread contributes its minutes to one account pool; there are no per-thread balances.

For example, 10 threads of Shared 240 put 2,400 browser-minutes a day in the pool, up to 600 in any rolling 60 minutes, with up to 10 threads' worth of browsers at once. Use them on 10 headless browsers for four hours, or on hundreds of one-minute jobs. The pool resets at midnight UTC and unused minutes don't carry over.

Minutes are metered to the second as [thread-seconds](https://cdpfleet.com/threads): a headful browser takes 2 threads, so it uses the pool twice as fast as a headless one.

## Prices

| Shared, per month | 5 threads | 10 threads | 25 threads | 50 threads | 100 threads | 500 threads | 1,000 threads |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Shared 60$1.50 / thread · 60 browser-minutes/day per thread | **$7.50**300 min/day · 75 min/hour | **$15**600 min/day · 150 min/hour | **$37.50**1,500 min/day · 375 min/hour | **$75**3,000 min/day · 750 min/hour | **$150**6,000 min/day · 1,500 min/hour | **$750**30,000 min/day · 7,500 min/hour | **$1,500**60,000 min/day · 15,000 min/hour |
| Shared 120$2 / thread · 120 browser-minutes/day per thread | **$10**600 min/day · 150 min/hour | **$20**1,200 min/day · 300 min/hour | **$50**3,000 min/day · 750 min/hour | **$100**6,000 min/day · 1,500 min/hour | **$200**12,000 min/day · 3,000 min/hour | **$1,000**60,000 min/day · 15,000 min/hour | **$2,000**120,000 min/day · 30,000 min/hour |
| Shared 240$2.50 / thread · 240 browser-minutes/day per thread | **$12.50**1,200 min/day · 300 min/hour | **$25**2,400 min/day · 600 min/hour | **$62.50**6,000 min/day · 1,500 min/hour | **$125**12,000 min/day · 3,000 min/hour | **$250**24,000 min/day · 6,000 min/hour | **$1,250**120,000 min/day · 30,000 min/hour | **$2,500**240,000 min/day · 60,000 min/hour |
| Shared 480$4 / thread · 480 browser-minutes/day per thread | **$20**2,400 min/day · 600 min/hour | **$40**4,800 min/day · 1,200 min/hour | **$100**12,000 min/day · 3,000 min/hour | **$200**24,000 min/day · 6,000 min/hour | **$400**48,000 min/day · 12,000 min/hour | **$2,000**240,000 min/day · 60,000 min/hour | **$4,000**480,000 min/day · 120,000 min/hour |

At full use the effective price per browser-hour is Shared 60 $0.050, Shared 120 $0.033, Shared 240 $0.021, Shared 480 $0.017 — see the [comparison with other cloud browsers](https://cdpfleet.com/pricing#compare).

## Before a session starts

All of these must hold, or the launch is refused with a clear status you can act on:

| Check | If not |
| --- | --- |
| A free thread | `429 threads_exceeded` — close a session or wait (`Retry-After: 1`). |
| Minutes left in today's pool | `429 daily_quota_exhausted` — `Retry-After` counts down to midnight UTC. |
| Minutes left in the rolling hour (25% of the pool) | `429 hourly_quota_exhausted` — the window rolls forward continuously. |
| Room in the shared fleet | `503 shared_capacity_full` — retry after 5 s. Dedicated threads are never refused for this. |

## Leases and timeouts

-   Shared sessions run on **15-minute leases** that renew automatically while shared capacity allows; a session can run up to 24 hours, within your remaining minutes.
-   The idle timeout is 120 seconds by default and up to 10 minutes on shared plans (idle minutes count); dedicated threads can keep a quiet browser open for up to 24 hours.
-   `keep_alive` (reconnect to the same browser after a disconnect) is a [dedicated-thread](https://cdpfleet.com/dedicated-threads) feature.
-   Short jobs should end themselves: `inactivity_timeout` and `overall_timeout` make a hung script stop billing — see the burst-jobs recipe below.

A burst-job session that ends itself after 15 s idle or 2 minutes

 

```node
// npm install playwright@1.60.0
// Browsers run on cdpfleet, so no `npx playwright install` is needed.
import { chromium } from 'playwright';

const KEY = process.env.CDPFLEET_API_KEY;

// 1. Launch the browser
const res = await fetch('https://starter.cdpfleet.com/chromium/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({
    proxy: 'http://user:pass@proxy.example.com:8080',
    headless: 'new',
    inactivity_timeout: '15s',
    overall_timeout: '2m',
  }),
});
if (!res.ok) throw new Error(`launch failed: ${res.status} ${await res.text()}`);
const { wsUrl } = await res.json();

// 2. Connect and drive it
const browser = await chromium.connect(wsUrl, { headers: { 'x-api-key': KEY } });
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close(); // ends the session and stops billing
```

```python
# pip install playwright==1.60.0 requests
# Browsers run on cdpfleet, so no `playwright install` is needed.
import os
import requests
from playwright.sync_api import sync_playwright

KEY = os.environ["CDPFLEET_API_KEY"]

# 1. Launch the browser
res = requests.post(
    "https://starter.cdpfleet.com/chromium/session",
    headers={"x-api-key": KEY},
    json={
        "proxy": "http://user:pass@proxy.example.com:8080",
        "headless": "new",
        "inactivity_timeout": "15s",
        "overall_timeout": "2m",
    },
    timeout=60,
)
res.raise_for_status()
ws_url = res.json()["wsUrl"]

# 2. Connect and drive it
with sync_playwright() as p:
    browser = p.chromium.connect(ws_url, headers={"x-api-key": KEY})
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.title())
    browser.close()  # ends the session and stops billing
```

```java
// Maven: com.microsoft.playwright:playwright:1.60.0  and  com.google.code.gson:gson:2.11.0
// Run with PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1: browsers run on cdpfleet.
import com.google.gson.JsonParser;
import com.microsoft.playwright.*;
import java.net.URI;
import java.net.http.*;
import java.util.Map;

public class Example {
  public static void main(String[] args) throws Exception {
    String key = System.getenv("CDPFLEET_API_KEY");

    // 1. Launch the browser
    String body = """
        {
          "proxy": "http://user:pass@proxy.example.com:8080",
          "headless": "new",
          "inactivity_timeout": "15s",
          "overall_timeout": "2m"
        }
        """;
    HttpResponse<String> res = HttpClient.newHttpClient().send(
        HttpRequest.newBuilder(URI.create("https://starter.cdpfleet.com/chromium/session"))
            .header("x-api-key", key)
            .header("content-type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build(),
        HttpResponse.BodyHandlers.ofString());
    if (res.statusCode() != 200) {
      throw new RuntimeException("launch failed: " + res.statusCode() + " " + res.body());
    }
    String wsUrl = JsonParser.parseString(res.body()).getAsJsonObject().get("wsUrl").getAsString();

    // 2. Connect and drive it
    try (Playwright playwright = Playwright.create()) {
      Browser browser = playwright.chromium().connect(wsUrl,
          new BrowserType.ConnectOptions().setHeaders(Map.of("x-api-key", key)));
      Page page = browser.newPage();
      page.navigate("https://example.com");
      System.out.println(page.title());
      browser.close(); // ends the session and stops billing
    }
  }
}
```

```csharp
// dotnet add package Microsoft.Playwright --version 1.60.0
// Browsers run on cdpfleet, so no `playwright install` is needed.
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using Microsoft.Playwright;

var key = Environment.GetEnvironmentVariable("CDPFLEET_API_KEY")!;

// 1. Launch the browser
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("x-api-key", key);
var body = """
    {
      "proxy": "http://user:pass@proxy.example.com:8080",
      "headless": "new",
      "inactivity_timeout": "15s",
      "overall_timeout": "2m"
    }
    """;
var res = await http.PostAsync("https://starter.cdpfleet.com/chromium/session",
    new StringContent(body, Encoding.UTF8, "application/json"));
if (!res.IsSuccessStatusCode)
    throw new Exception($"launch failed: {(int)res.StatusCode} {await res.Content.ReadAsStringAsync()}");
var wsUrl = (await res.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("wsUrl").GetString()!;

// 2. Connect and drive it
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.ConnectAsync(wsUrl, new BrowserTypeConnectOptions
{
    Headers = new Dictionary<string, string> { ["x-api-key"] = key },
});
var page = await browser.NewPageAsync();
await page.GotoAsync("https://example.com");
Console.WriteLine(await page.TitleAsync());
await browser.CloseAsync(); // ends the session and stops billing
```

```go
// go get github.com/playwright-community/playwright-go@v0.6000.0
//
// One-time driver setup (needs Node.js 18+): playwright-go can no longer download the
// 1.60.0 driver itself, so build it from npm and point PLAYWRIGHT_DRIVER_PATH at it:
//   mkdir -p ~/.cache/pw-driver-1.60.0 && cd ~/.cache/pw-driver-1.60.0 &&
//     curl -sL https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz | tar xz &&
//     ln -sf "$(command -v node)" node
//   export PLAYWRIGHT_DRIVER_PATH=~/.cache/pw-driver-1.60.0
// Browsers run on cdpfleet, so no browsers are downloaded (SkipInstallBrowsers).
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/playwright-community/playwright-go"
)

func main() {
	key := os.Getenv("CDPFLEET_API_KEY")

	// 1. Launch the browser
	body := `{
	  "proxy": "http://user:pass@proxy.example.com:8080",
	  "headless": "new",
	  "inactivity_timeout": "15s",
	  "overall_timeout": "2m"
	}`
	req, _ := http.NewRequest("POST", "https://starter.cdpfleet.com/chromium/session", strings.NewReader(body))
	req.Header.Set("x-api-key", key)
	req.Header.Set("content-type", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		msg, _ := io.ReadAll(res.Body)
		log.Fatalf("launch failed: %s %s", res.Status, msg)
	}
	var session struct {
		WsURL string `json:"wsUrl"`
	}
	if err := json.NewDecoder(res.Body).Decode(&session); err != nil {
		log.Fatal(err)
	}

	// 2. Connect and drive it (Install fetches only the Playwright driver, once)
	opts := &playwright.RunOptions{SkipInstallBrowsers: true}
	if err := playwright.Install(opts); err != nil {
		log.Fatal(err)
	}
	pw, err := playwright.Run(opts)
	if err != nil {
		log.Fatal(err)
	}
	defer pw.Stop()
	browser, err := pw.Chromium.Connect(session.WsURL, playwright.BrowserTypeConnectOptions{
		Headers: map[string]string{"x-api-key": key},
	})
	if err != nil {
		log.Fatal(err)
	}
	page, err := browser.NewPage()
	if err != nil {
		log.Fatal(err)
	}
	if _, err := page.Goto("https://example.com"); err != nil {
		log.Fatal(err)
	}
	title, _ := page.Title()
	fmt.Println(title)
	browser.Close() // ends the session and stops billing
}
```

## Shared or dedicated?

Shared threads fit bursty and scheduled work — crawls, monitoring, tests — where the browsers don't run around the clock. If a browser runs most of the day, a [dedicated thread](https://cdpfleet.com/dedicated-threads) at $8.50 a month with unlimited minutes is cheaper per hour ($0.012 at 24/7) and never waits for shared capacity.

|  | Community | Shared | Dedicated |
| --- | --- | --- | --- |
| Price | Free | $1.50–$4 per thread / month | $8.50 per thread / month |
| Concurrent browsers | 2 threads | Up to your thread count | Up to your thread count |
| Daily browser-minutes | 60 per thread | Each thread adds its minutes to one account pool | Unlimited |
| Rolling-hour limit | 25% of the daily pool in any 60 minutes | 25% of the daily pool in any 60 minutes | None |
| Session length | Up to 15 minutes | Up to 24 h | Up to 24 h |
| Session leases | Lowest priority, 5-minute leases | 15-minute leases, renewed automatically while shared capacity allows | None — capacity is reserved |
| Idle timeout | 120 s by default, up to 5 min | 120 s by default, up to 10 min | 120 s by default, up to 24 h |
| Launch rate | At least 2 per second and 10 per minute | Threads ÷ 5 per second, threads × 6 per minute (at least 2 and 10) | Twice the shared rate: threads ÷ 5 × 2 per second, threads × 12 per minute |
| Proxies | Included (shared), or your own | Your own, the residential add-on, or the free Community proxy | Your own, the residential add-on, or the free Community proxy |
| Per session | 50 open pages, 2 GB memory | 50 open pages, 4 GB memory | 50 open pages, 6 GB memory |
| Recordings, profiles, keep-alive, kept downloads | Not included | Recordings, kept downloads, and profiles: 20 per thread (at least 100) | Recordings, kept downloads, keep-alive, and profiles: 30 per thread (at least 100) |
| Sizes | One size, one per card | 5–1,000 threads | 5–10,000 threads, custom above |

## Related

Cases, recipes, posts and comparisons about this — updated as new ones are published.

### Reference docs

The details, options and errors.

-   [Plans & pricing](https://cdpfleet.com/docs/pricing)Sizes, pools and the price matrix.
-   [Sessions & billing](https://cdpfleet.com/docs/sessions)How threads and minutes are metered.
-   [Errors & limits](https://cdpfleet.com/docs/errors)Every refusal and what to do.

### Cases 9

Real problems solved end to end, run on production in five languages.

-   [Case 80: How many tabs fit in one session, by plan, browser and "memory"](https://cdpfleet.com/docs/cases/tabs-and-memory-by-plan)A long Wikipedia article opened in one new tab after another until the session ends: on Community (2 GB), a shared plan (4 GB) and a dedicated thread (6 GB), in…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/80-tabs-and-memory-by-plan)
-   [Case 78: keep\_alive: an agent run that survives its client going away](https://cdpfleet.com/docs/cases/keep-alive-reconnect)An agent works through a catalogue in a headless Chrome session with `keep_alive`, then its client disconnects. A new client reconnects to the same session and…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/78-keep-alive-reconnect)
-   [Case 76: The SDK vs plain Playwright: the same scrape, and what happens at the thread cap](https://cdpfleet.com/docs/cases/sdk-vs-plain-playwright)One small scrape written three ways in each language: a launch request of your own plus Playwright, the cdpfleet SDK, and the SDK's connect URL. The scrape is the…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/76-sdk-vs-plain-playwright)
-   [Case 72: Stay under the tab and memory caps: reuse a few pages, close what you're done with](https://cdpfleet.com/docs/cases/stay-under-the-caps)Every session has a tab cap and a memory cap. A new tab per URL runs into the first; one page that grows runs into the second. A small pool of reused tabs works…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/72-stay-under-the-caps)
-   [Case 58: Do it by hand in live view, then let your code finish in the same browser](https://cdpfleet.com/docs/cases/launch-interactive-to-code)Launch a browser with `start_url` and no client, drive it through a control-mode live link — address bar, Tab, typing — then connect your code: it finds the person's…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/58-launch-interactive-to-code)
-   [Case 50: A price watcher in one program: two snapshots minutes apart, diffed, billed only while reading](https://cdpfleet.com/docs/cases/price-watch)Take a snapshot of a catalogue price and a live market price, wait two minutes, take another and diff them field by field. Each snapshot is its own short session, so…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/50-price-watch)
-   [Case 30: Five pages at once: parallel tabs in one browser session](https://cdpfleet.com/docs/cases/parallel-pages)Open five unrelated pages concurrently in one session and compare with loading them one by one — same thread, same proxy, a fraction of the wall time.[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/30-parallel-pages)
-   [Case 20: Three visitors, one thread: browser contexts instead of sessions](https://cdpfleet.com/docs/cases/contexts-not-sessions)Cookies, storage, locale and clock isolated per persona inside a single browser session — what a context gives you for free, what it shares, and the proxy surprise…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/cases/20-contexts-not-sessions)

[All cases →](https://cdpfleet.com/docs/cases) 9 match this topic

### Recipes 6

Complete programs for one setup each.

-   [Short-lived sessions for burst jobs](https://cdpfleet.com/docs/examples#burst-timeouts)For many small jobs, make each session end itself: 15 seconds idle or 2 minutes total, whichever comes first, so a hung script never bills for long. Values take `s`,…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/burst-timeouts)
-   [Chrome you can disconnect from and come back to](https://cdpfleet.com/docs/examples#chrome-keep-alive)`keep_alive: true` (dedicated threads) keeps the browser when your code disconnects: reconnect to the same `wsUrl` within `inactivity_timeout` and your contexts,…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/chrome-keep-alive)
-   [Microsoft Edge over CDP that survives a disconnect](https://cdpfleet.com/docs/examples#edge-keep-alive)`keep_alive: true` (dedicated threads) with `"cdp": true`: disconnect from `cdpUrl`, reconnect within `inactivity_timeout` and your pages are where you left them.…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/edge-keep-alive)
-   [A hard time cap for batch jobs](https://cdpfleet.com/docs/examples#overall-timeout-cap)`overall_timeout` ends the session at a fixed time after launch, busy or not. `inactivity_timeout` is different: it only ends a quiet session. Use the cap so a stuck…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/overall-timeout-cap)
-   [Headful Opera over CDP that survives a disconnect](https://cdpfleet.com/docs/examples#opera-keep-alive)`keep_alive: true` (dedicated threads) with `"cdp": true` on headful Opera: disconnect, reconnect to the same `cdpUrl` within `inactivity_timeout`, and the default…[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/opera-keep-alive)
-   [Long-running session](https://cdpfleet.com/docs/examples#long-session)Keep a session alive for up to two hours and tolerate five idle minutes. Both are capped by your plan.[Code on GitHub](https://github.com/cdpfleet/cdpfleet/tree/main/examples/recipes/long-session)

### Updates 1

Product news and browser releases.

-   [50 tabs per session, memory as the ceiling, and the memory option](https://cdpfleet.com/docs/updates/tabs-and-memory)Every plan now allows 50 tabs in one session; what actually limits a session is its memory — 2, 4 or 6 GB by plan — and the new "memory" launch option buys 2–4 times…

### Compared with other services 18

Prices, limits and features.

-   [cdpfleet vs Browserbase](https://cdpfleet.com/docs/compare/cdpfleet-vs-browserbase)Twelve real browsers over Playwright or CDP with your own proxies, or Chromium over CDP with built-in proxies, Stagehand and captcha solving. Prices, limits and…
-   [cdpfleet vs Browserless](https://cdpfleet.com/docs/compare/cdpfleet-vs-browserless)The longest-running headless-browser service against a browser fleet: 30-second "units" with 2–60-minute session caps and proxies by the megabyte, or threads metered…
-   [cdpfleet vs Steel](https://cdpfleet.com/docs/compare/cdpfleet-vs-steel)The open-source browser API for agents against a browser fleet: per-minute Chromium with proxies, captcha solves and a 15-minute-to-24-hour session cap by plan, or…
-   [cdpfleet vs Browser Use Cloud](https://cdpfleet.com/docs/compare/cdpfleet-vs-browser-use)The cheapest per-hour cloud browser for AI agents against a fleet of real browsers: one stealth Chromium over CDP at $0.02/hour plus traffic fees, or twelve browsers…
-   [cdpfleet vs Hyperbrowser](https://cdpfleet.com/docs/compare/cdpfleet-vs-hyperbrowser)A credits-based cloud Chrome with stealth, captcha solving and AI agents against a fleet of twelve real browsers: $0.10/hour plus $10/GB for its proxies (your own…
-   [cdpfleet vs Cloudflare Browser Run (Browser Rendering)](https://cdpfleet.com/docs/compare/cdpfleet-vs-cloudflare-browser-run)Cloudflare's serverless headless Chromium — formerly Browser Rendering — against a fleet of twelve real browsers: $0.09/hour beyond 10 free hours plus concurrency…
-   [cdpfleet vs Anchor Browser](https://cdpfleet.com/docs/compare/cdpfleet-vs-anchor-browser)An agent-focused cloud Chromium with captcha solving, managed logins and US hosting against a fleet of twelve real browsers: per-browser and per-hour fees plus…
-   [cdpfleet vs Kernel](https://cdpfleet.com/docs/compare/cdpfleet-vs-kernel)A sandboxed cloud Chromium for agents, billed per second with free standby, against a fleet of twelve real browsers on flat threads: $0.06/hour headless but…

[All compared with other services →](https://cdpfleet.com/docs/compare) 18 match this topic

## Read next

[Threads →](https://cdpfleet.com/threads)[Dedicated threads →](https://cdpfleet.com/dedicated-threads)[Community plan →](https://cdpfleet.com/community)[Pricing →](https://cdpfleet.com/pricing)

---
Source: https://cdpfleet.com/shared-threads · Markdown: https://cdpfleet.com/shared-threads.md · All docs for AI tools: https://cdpfleet.com/llms.txt
