Skip to main content

Platform limits

This is the whole platform's limits table in one page: how big a request can be, what you may name things, what a new project is allowed to run, how long things wait before giving up, and how long credentials live. Every number here comes from the code that enforces it.

Two things to know before you read on:

  • Most limits are defaults, not laws. Where a limit is backed by a setting (shown in the last column), the operator running your platform can change it. Where a limit is a hard rule of the API, it says so.
  • Check your own project's live limits with GET /v1/projects/{projectID}/quota or the console's Quota page — that reads the cluster's own enforcement rather than this table. See Quotas and audit.

Request body and upload sizes

Exceeding these returns 400, or the request is refused before it is read. Two paths answer 413 instead: a direct POST to a deployed function (the language shims) and an upload through the console's proxy.

WhatLimitNotes
Most core API JSON bodies (agent-engine-api)8 KiBUsers, orgs, projects, members, invitations, keys, service accounts
Agent or function code upload100 MiBPlus 1 MiB of slack for the form fields. Setting: MAX_UPLOAD_BYTES
Stored source file (browser editor)1 MiB per file200 files per agent; an uploaded archive may expand to at most 64 MiB
Agent invoke request1 MiBApplies to invoke, streaming invoke, and memorize
Agent invoke upstream response32 MiBA larger response from the agent becomes a 502
Function event body (the runtime shim)8 MiBThe cap on a direct POST to a deployed function
Per-agent secrets body1 MiBPUT and PATCH on /v1/agents/{name}/secrets
Project secret create body128 KiBThe value itself is capped separately, below
Project secret value65536 bytes (64 KiB)400 — secret value is N bytes, limit is 65536
Secret binding body8 KiBPUT on a secret map
MCP server create body4 KiBOnly name and expose are read
MCP tool publish body1 MiBIt carries Python source
Serverless API body256 KiBEvery route on serverless-api
VectorDB body32 MiBSetting: MAX_BODY_BYTES
VectorDB query filter64 KiB400 — filter is too large
MemoryStore create body16 KiB
Pub/Sub publish body4 MiBEvery other Pub/Sub body is capped at 1 MiB
Sandboxed tool call body1 MiBThe tool's own response is capped at 8 MiB

Pagination and batch sizes

WhatDefaultMaximumNotes
page_size on every list endpoint50200limit is accepted as an alias. A larger value is rejected with 400 — page_size must be between 1 and 200 — never clamped
page_tokenOpaque, tamper-evident, and bound to the list that issued it. A token from another list is 400 — page_token is invalid or was issued for a different list; start from the first page
VectorDB points per upsert1000All-or-nothing: one bad point rejects the whole batch. Setting: MAX_POINTS_PER_REQUEST
VectorDB top_k per query101000Setting: MAX_TOP_K
VectorDB scroll page501000The point browser
VectorDB ids per delete-points call1000
VectorDB collections listed in a direct-access credential256Beyond that the response sets truncated: true
Pub/Sub messages per publish100400 — a publish carries at most 100 messages (got N)
Pub/Sub messages per pull10100Over-asks are silently capped, not rejected
Pub/Sub acknowledgement ids per call1000
Agent log history lines500The limit query parameter on the history endpoint
Serverless log tail lines50010000The tail query parameter; minimum 1. Setting: LOG_TAIL_LINES

Name rules

Names are chosen once and cannot be changed — renaming would move the address other things depend on.

ResourceRuleLength
Agent or function^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$ — a lowercase DNS label≤ 63
Serverless service^[a-z]([-a-z0-9]{0,50}[a-z0-9])?$1–52 (shorter than 63 because revision names append -00001)
MCP server^[a-z]([a-z0-9-]{0,38}[a-z0-9])?$≤ 40
MCP tool^[a-z][a-z0-9_]{0,62}$ — a lowercase identifier, no leading underscore≤ 63
VectorDB index[a-z0-9]([a-z0-9-]*[a-z0-9])? — no uppercase, no underscore≤ 48
MemoryStore instance^[a-z]([-a-z0-9]*[a-z0-9])?$1–40
Pub/Sub topic and subscription^[a-z]([a-z0-9-]*[a-z0-9])?$≤ 63
Project secret^[a-zA-Z0-9][a-zA-Z0-9_-]{0,62}$1–63
Environment variable / secret key^[A-Za-z_][A-Za-z0-9_]*$
Service accountA lowercase DNS label. Reserved permanently, even after deletion, so a new principal can never inherit an old one's grants
session_id^[A-Za-z0-9_.-]{1,128}$≤ 128
user_id^[A-Za-z0-9_.:@-]{1,128}$≤ 128
A session id you choose yourself while unauthenticatedMust be at least 24 characters of unguessable randomness — or omit it and the platform generates one≥ 24
PasswordMinimum 12 characters≥ 12

Agents and functions share one flat name space per project: a function cannot take a name an agent already holds.

crusoe-cloud-credential is a reserved secret name. Nineteen environment variable names are reserved and cannot be bound to a secret — they are listed in the Secrets API.

Default project quotas

Written into every new project at creation. A hard value of 0 means that resource is unlimited. Nothing in the API raises a cap — ask your platform operator.

ResourceDefaultShown in the console as
Running instances (pods)50Running instances
Kubernetes Services30Services
CPU reserved (requests)10CPU (reserved)
Memory reserved (requests)20 GiBMemory (reserved)
CPU maximum (limits)20CPU (max)
Memory maximum (limits)40 GiBMemory (max)
Pub/Sub backlog storage1 GiB per project(Pub/Sub quota page)
Pub/Sub topics100 per project
Pub/Sub producers and consumers100 each, per topic

Per-container defaults are applied when you do not set your own: a limit of 2 CPU / 4 GiB and a request of 100m CPU / 256 MiB.

Two quota traps worth learning once

Every serverless revision permanently holds two Kubernetes Services (one public, one private), and every deploy or spec edit creates a revision. Once the Services quota is full, new revisions across the whole project stop becoming ready until you delete services you no longer need.

Pub/Sub budget is spent by claim, not by use. A topic reserves its max_bytes the moment it exists, so four empty 16 MiB topics have already spent 64 MiB. Consuming messages does not give budget back — delete a topic or lower its max_bytes.

If some older material quotes 60 Kubernetes Services, that is a fallback value used only when a project is created without the field; projects created by the platform's own control plane get 30. Your live number is always in GET /v1/projects/{projectID}/quota.

Timeouts

WhatDefaultMaximumSetting
Agent invoke (control plane waits this long for the agent)60 sINVOKE_TIMEOUT_SECONDS
Serverless request timeout300 s3600 stimeout_seconds, mirrored into the container as CRUSOE_REQUEST_TIMEOUT_SECONDS
MCP server request timeout300 s
run_python sandbox execution20 s60 stimeout_s on the execute call; 400 — timeout_s must be between 1 and 60
Sandboxed tool call30 s120 stimeout_s; 400 — timeout_s must be between 1 and 120
Waiting for a warm sandbox pod30 sThen 503 — no warm sandbox pod available, try again shortly
A tool sandbox becoming ready110 sTool calls have no warm pool, so they pay pod scheduling and image pull
Pub/Sub pull long-poll wait2000 ms20000 mstimeout_ms
Pub/Sub acknowledgement deadline30 s600 s (minimum 1 s)ack_deadline_seconds. On a push subscription this doubles as the per-request timeout — leave room for a cold start
MemoryStore API request30 sREQUEST_TIMEOUT_SECONDS
MemoryStore live stats read3 s
Scale to zero after idleabout 90 sPoll for zero instances with a generous timeout rather than sleeping a fixed time
A stale build claim is reclaimable after30 minUntil then a second deploy gets 409 — a build is already in progress for agent <name>
platformctl deploy waiting for readypolls every 2 s, up to 5 min
platformctl invoke client timeout5 min

Retention and history

WhatRetentionNotes
Persisted agent logs14 daysSurvives scale-to-zero and revision rollouts. Setting: LOG_RETENTION
Live agent and serverless logsnoneStreamed from the newest running instance only; an idle, scaled-to-zero workload has no live logs (you get 200 and an explanation, not an error)
Audit logkept, but with no export, no retention policy, and no date-range filter yetAlpha. See Break-glass and audit
Metrics historynoneThe platform reports live instance counts and readiness; there are no historical charts, because no time-series database is deployed
Stored agent sourcelatest version onlyNo history, no version control — copy anything you want to keep
Pub/Sub messagesonly while some subscription still owes an acknowledgementCreate subscriptions before publishing, or the message is reclaimed
VectorDB and MemoryStore datauntil you delete itNo snapshots, no backups, no restore. Deleting an index or an instance is irreversible

Credentials, tokens, and sign-in

WhatValueNotes
Session token lifetime12 hoursHMAC-signed and stateless, so it is not revocable before it expires
API key expiry0 (never expires) or 1–3650 days400 — expires_in_days must be between 1 and 3650, or 0 for a key that does not expire
API key secret visibilityshown exactly once, at creationOnly a hash is stored. Lost it? Revoke the key and create another
Sign-in throttle10 attempts per IP and 50 per account, per 15 minutes429 with a Retry-After header
Password minimum12 charactersSame rule for new accounts, changes, and invitation acceptance
Break-glass grant4 hours by default, 24 hours maximumReason required, at least 8 characters, shown verbatim to the project's members
Secret read token (:issue-token)300 s by defaultClamped to 3600 s. The store's own maximum lease may clamp it further — trust the returned ttl_seconds
Pub/Sub direct broker tokennever expiresRevoking one means rotating the platform signing key for everyone
VectorDB direct-access tokennon-expiring by defaultSetting: QDRANT_JWT_TTL. Scoped to the exact collections that existed when it was minted, so refetch after creating an index
MCP server bearer tokenminted once, reused across redeploysFormat: cai_mcp_ plus 64 hexadecimal characters
Invitation tokenshown exactly once, and expiresSend the accept link immediately — it cannot be retrieved later

Rate limits

APILimitWhat you see
agent-engine-apiPer-principal token bucket, tuned by the operator (RATELIMIT_RPS / RATELIMIT_BURST); anonymous callers are limited per IP429
serverless-api100 requests/second, burst 200, per principal per API replica; /healthz is exempt429
VectorDB, MemoryStore, Pub/SubPer-principal token bucket on every route except health checks429

Service defaults worth knowing

These are not caps — they are what you get when you do not say otherwise.

ServiceDefault
Serverless scalingminimum 0 instances, maximum 10, 80 concurrent requests per instance
Serverless resources250m CPU / 512 MiB requested, 1 CPU / 512 MiB limit — applied only when you send no resources at all
Serverless port8080; exactly one port, named http1 or h2c
Serverless maximum instancesSending max_scale: 0 on a serverless service behaves as 10, not unlimited. On an agent's config, max_scale: 0 does mean unbounded
Agent invoke authenticationopen to anonymous callers; the operator can close it. Writing to an agent's memory bank always requires a credential
Code sandbox warm pool3 pods kept ready; each pod runs one snippet and is destroyed. Execution pods are limited to 1 CPU / 512 MiB (requesting 50m / 128 MiB)
Sandboxed tool pods2 CPU / 1 GiB limit, 100m / 256 MiB request; no warm pool
VectorDB index1536 dimensions, cosine distance, 1 shard, 1 replica, no quantization. Dimensions accept 1–65536 and replicas 1–8; only replicas and payload placement can be changed later
MemoryStore size classessmall 256 MiB container / 192 MiB usable, medium 1 GiB / 768 MiB, large 4 GiB / 3 GiB — usable memory is 75% of the container, on purpose
MemoryStore persistenceon, with a 2 GiB volume; eviction policy noeviction (writes fail at the limit rather than dropping keys)
Pub/Sub topic16 MiB max_bytes, no age limit, discard: old
Pub/Sub subscriptiontype shared, 30 s acknowledgement deadline, 5 delivery attempts, 1000 unacknowledged messages in flight, start_from: all, pull delivery