Limits
The beta's default limits per organization, how to read your current usage against them, and what the API returns when you hit one.
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 ID | Product | Kind | Beta default | Unit | Window |
|---|---|---|---|---|---|
sandboxes.concurrent | sandboxes | concurrency | 10 | sandboxes | |
sandboxes.vcpu_max | sandboxes | size | 2 | vcpu | |
sandboxes.memory_max | sandboxes | size | 2048 | MiB | |
sandboxes.disk_max | sandboxes | size | 16 | GiB | |
sandboxes.timeout_max | sandboxes | duration | 3600 | seconds | |
vision.sessions.concurrent | vision | concurrency | 5 | sessions | |
vision.session.timeout_max | vision | duration | 1800 | seconds | |
vision.scrape.rpm | vision | rate | 60 | requests | 60 s |
vision.scrape.concurrent | vision | concurrency | 5 | requests | |
vision.crawl.pages_max | vision | size | 500 | pages | |
vision.crawl.concurrent | vision | concurrency | 1 | crawls | |
render.concurrent | render | concurrency | 2 | renders | |
routines.steps.daily | routines | quota | 50000 | steps | 86400 s |
actions.rpm | actions | rate | 300 | requests | 60 s |
infer.tpm.<model> | infer | rate | per model | tokens | 60 s |
egress.bytes.daily | platform | quota | per model | bytes | 86400 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:
bashcurl -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 code | When | What to do |
|---|---|---|
429 rate_limited | Too many requests in the current window | Wait Retry-After seconds |
429 concurrency_limited | Too many operations of one kind running at once | Wait for one to finish, or stop one |
429 quota_exceeded | A daily or monthly quota is used up | Wait for the window to reset |
422 limit_exceeded | One request asks for more than a limit allows, such as vcpu: 4 | Ask for less |
402 spend_cap_exceeded | The key reached its spend cap | Raise the cap or use another key |
402 credits_exhausted | The organization has no credits left | Add 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.