Limits keep one organization from crowding out the others on a shared node. Each limit has an ID, and the same ID appears wherever that limit shows up: in GET /v1/limits, in the limit member of an error and in the RateLimit-Policy header.

Beta defaults

These apply per organization unless your account says otherwise:

Limit IDProductKindBeta defaultUnitWindow
sandboxes.concurrentsandboxesconcurrency10sandboxes
sandboxes.vcpu_maxsandboxessize2vcpu
sandboxes.memory_maxsandboxessize2048MiB
sandboxes.disk_maxsandboxessize16GiB
sandboxes.timeout_maxsandboxesduration3600seconds
vision.sessions.concurrentvisionconcurrency5sessions
vision.session.timeout_maxvisionduration1800seconds
vision.scrape.rpmvisionrate60requests60 s
vision.scrape.concurrentvisionconcurrency5requests
vision.crawl.pages_maxvisionsize500pages
vision.crawl.concurrentvisionconcurrency1crawls
render.concurrentrenderconcurrency2renders
routines.steps.dailyroutinesquota50000steps86400 s
actions.rpmactionsrate300requests60 s
infer.tpm.<model>inferrateper modeltokens60 s
egress.bytes.dailyplatformquotaper modelbytes86400 s

Model limits differ per model; GET /v1/infer/models lists each model's tokens per minute and requests per minute for you. Each product's limits page lists the size limits of single requests, such as the most URLs in one batch.

Read your limits

Any valid credential can read the limits that apply to it, with current usage:

bash
curl -s https://beta-api.b3os.org/v1/limits -H "Authorization: Bearer $B3OS_API_KEY"
json
{ "object": "limits", "spend": { "cap_usd": 50, "used_usd": 1.42, "period_start": "2026-10-01T00:00:00.000Z", "period_end": "2026-11-01T00:00:00.000Z" }, "items": [ { "id": "sandboxes.concurrent", "product": "sandboxes", "kind": "concurrency", "limit": 10, "unit": "sandboxes", "current": 2 }, { "id": "vision.scrape.rpm", "product": "vision", "kind": "rate", "limit": 60, "unit": "requests", "window_s": 60, "current": 14, "reset_s": 38 } ]}

This example is abridged. spend shows the calling key's spend cap and what it has used this period.

When you hit a limit

Status and codeWhenWhat to do
429 rate_limitedToo many requests in the current windowWait Retry-After seconds
429 concurrency_limitedToo many operations of one kind running at onceWait for one to finish, or stop one
429 quota_exceededA daily or monthly quota is used upWait for the window to reset
422 limit_exceededOne request asks for more than a limit allows, such as vcpu: 4Ask for less
402 spend_cap_exceededThe key reached its spend capRaise the cap or use another key
402 credits_exhaustedThe organization has no credits leftAdd credits in the dashboard

429 responses carry Retry-After and the RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset and RateLimit-Policy headers. The problem body repeats the wait as retry_after_s and names the limit in limit:

json
{ "type": "https://docs.beta.b3os.org/errors#rate_limited", "title": "Rate limited", "status": 429, "code": "rate_limited", "detail": "60 scrapes per minute allowed; retry in 12 seconds", "instance": "req_01m5t4yg394wegr3j4y01qb363", "retry_after_s": 12, "limit": { "id": "vision.scrape.rpm", "limit": 60, "unit": "requests", "window_s": 60, "current": 60 }}

The SDKs retry 429 and 5xx responses of idempotent calls with jittered backoff. Your own clients should wait at least Retry-After seconds before trying again.

Limits on the node

The node enforces the limits on sandboxes, inference tokens and egress itself, with counters it refreshes from the edge every few seconds. Calls from inside a sandbox never pass through the edge and are capped all the same.

Ask a question... ⌘I