Skip to content

Limits & rate limits

Limits are set per tier and enforced by the API from your key's server-side record — not from the key prefix. Every tier runs the same microVMs; limits gate concurrency, session duration, and request rate, never isolation or per-fork performance.

LimitDemoProEnterprise
Concurrent sandboxes2no limitunlimited
Parallel sandboxes (fan-out width)shared self-serveunbounded, auto-scaledunlimited
Fork fan-out (per group)up to 1000unboundedunbounded
Max session duration1 hour24 hoursunlimited
Request rateshared self-serve capper-tenant, highper-tenant, custom

"Unlimited" on Enterprise means the API applies no cap (limit 0 = no cap in the key record). Pro has no concurrent-sandbox cap either; it is built to run at extreme width, and capacity scales with your workload.

Width — how you fan out to hundreds or thousands. Two paths, and only the second involves the fork fan-out number above:

  • Parallel sandboxesindependent sandboxes spread across the fleet, autoscaled onto more nodes. Declare how wide you expect to fan out with Env.expect(N) (a hint the platform provisions for — not a knob you turn); Pro has no width quota, so capacity scales with your workload. Hundreds-to-thousands of parallel rollouts — a wide GRPO run — live here.
  • Live-fork fan-outfork(count=N) clones one running parent into N copy-on-write children that share its RAM on the parent's node (≈3 ms, no cold start). Because the children pin to one node, a single fork call is batched. Session.fork_group(n) chunks a wider CoW group across calls transparently and enforces strict width — reach for it, not raw fork, whenever you want a group larger than one batch. Demo groups fan out to 1,000; on Pro and Enterprise the group is effectively unbounded.
  • Concurrency — creating a sandbox past your cap returns 429 quota_exceeded (on Demo, a friendly 403 demo_tier_limit that says what to do). Suspend or delete a live sandbox, or upgrade.
  • Request rate — exceeding your per-key rate returns 429 rate_limited with a Retry-After header. The bucket is keyed by your key id, so another tenant on a shared egress IP can't throttle you, and rotating IPs can't dodge it.
  • Session duration — a sandbox that outlives your tier's max session is reaped. Persist anything you need and re-create, or suspend before the cap.

Back off with exponential jitter and honor Retry-After:

import time, random
def with_backoff(fn, tries=5):
for i in range(tries):
try:
return fn()
except RateLimited as e:
wait = e.retry_after or random.uniform(0, 0.5 * 2**i)
time.sleep(wait)
raise

The collimate-rl SDK already does bounded, full-jitter backoff for 429/503, so a fanned-out GRPO group degrades gracefully instead of hammering the API.