sharkmagic.docs
Limits

Agent? Fetch sharkmagic.si/docs/llms.txt or this page as markdown

Limits#

What the hosted node enforces at launch. Your account's live values are authoritative: GET /v1/quotas (your quotas with current use) and GET /v1/capabilities (the node's limits and features, no auth). Do not hard-code the numbers below in an agent; read them.

curl -sS https://hel1.sharkmagic.si/v1/capabilities
shark quotas --json      # or GET /v1/quotas on the node with a node token (api.md, "Auth")

Every limit below answers with a stable error code when you hit it (errors.md); none is a silent cap.

Your account#

The account service sets per-account caps; the node enforces them and GET /v1/quotas shows each as a row with limit and used (scope: tenant): spaces (held, awake or hibernated), awake_spaces, concurrent_leases. The same answer names your account's class (limits_class) and how to raise a limit (raise). Defaults at launch, by class (an account can be given others; your rows are the truth):

cap new account (first 7 days) running on promotional credit only standard partner when exceeded
Spaces held 20 10 50 200 429 quota_exceeded, details.quota: spaces: delete one
Spaces awake at once 7 7 7 100 429 quota_exceeded, details.quota: awake on create, fork or wake: hibernate one (shark hibernate, or shark space set <space> --idle 30m so idle ones sleep by themselves)
commands running at once 4 2 6 12 queued, then 429 lease_cap_reached (retryable, the command did not start)
exposed processes awake at once 2 1 3 20 refused with quota_exceeded: stop or sleep one
CPU per command 4 CPUs 2 CPUs the VM's 8 vCPU the VM's 8 vCPU none: the command runs slower

A Space does not hibernate by itself unless it, or the node, has an idle setting: hibernate the ones you are not using.

Every 429 quota_exceeded names the cap (details.quota, limit, used), your details.limits_class and details.raise: how to get more (write to support@sharkmagic.si; design partners and SDK platforms get the partner limits). Prices are the same in every class.

shark quotas --json      # {"limits_class": "partner", "raise": "...", "data": [{"name": "awake_spaces", "scope": "tenant", "limit": 100, "used": 12}, ...]}
curl -sS -H "Authorization: Bearer $SHARK_API_KEY" https://api.sharkmagic.si/v1/limits   # class, caps, label caps (no use)

Partner limits#

For design partners and SDK platforms whose own end users each get Spaces: the partner class, set by Shark (ask us; an operator turns it on with one command and it reaches the nodes within seconds). Its numbers are sized to what one node serves: 200 Spaces is the node's per-account ceiling, 100 awake is a quarter of the node's 400 live Spaces. The node's own protections still apply on top of any class: 50 GiB of disk per account, and its admission (503 out_of_capacity while memory or CPU is short, retryable).

Per-label limits#

A platform can cap each of its own end users by a label of their Spaces (Spaces take labels at create, fork and PATCH). A selector key caps each value of that label on its own; key=value caps that one value and wins over key for it. Two counts: awake (Spaces awake at once) and spaces (held). A Space without the label is not capped by it. They only tighten: the account's caps above still apply.

shark quotas labels set end_user --awake 3 --spaces 20     # every end user: 3 awake, 20 held
shark quotas labels set end_user=acme --awake 10            # acme gets 10 awake
shark quotas labels --json                                  # {"class": ..., "label_caps": {"end_user": {"awake": 3, "spaces": 20}, ...}}
shark quotas labels rm end_user=acme
# HTTP (account service): PATCH /v1/limits/labels {"labels": {"end_user": {"awake": 3}}}  (null removes a selector)
#                         PUT   /v1/limits/labels {"labels": {...}}                       (replaces all; null clears)
limit value when exceeded
selectors per account 32; key [A-Za-z0-9._/-]{1,63}, value 1–255 chars 400 invalid_request, details.field
a value's Spaces awake / held what you set (integer 0–1,000,000; 0 = none allowed) 429 quota_exceeded, details.quota: label_awake or label_spaces, details.label (end_user=alice), details.selector, limit, used; on create, fork, wake and on a PATCH that moves a Space into a full value

GET /v1/quotas shows one row per selector and count (scope: label): for key=value its use; for key the fullest value (label, used) and how many values you use (values). A change reaches the nodes within one poll of the account service (about 2 s).

Commands#

limit value when exceeded
lease shape (each command's microVM) 8 vCPU, 4 GiB —
timeout_s, sync exec (JSON when it ends) default 120 s, max 900 s 400 invalid_request, details.max_s: 900
timeout_s, streaming (Accept: text/event-stream) or async ("wait": false) default 30 min, max 7,200 s (2 h) 400 invalid_request, details.max_s: 7200
output returned by a sync exec last 1 MiB of each stream (stdout_truncated: true) the full output stays in the op log
op log (stored output per op) 32 MiB per stream, then truncated
op retention (result and output) 7 days 410 op_expired; the commit stays in audit
cmd 1 B – 256 KiB 400
stdin 1 MiB 413 payload_too_large
env per request 128 names, 16 KiB per value 400
op_id 1–64 of [A-Za-z0-9_.:-] 400 invalid_op_id
commands running at once, per account your account's cap (above; then a queue; too long a wait gives 429 lease_cap_reached before the command starts) 429, retryable
node admission (memory and CPU) the node refuses new commands, Spaces and wakes while its memory is short or its CPUs are saturated; live state: the node_admission row of GET /v1/quotas 503 out_of_capacity with Retry-After (details.reason), retryable; nothing started
stdin streaming into a running command (stdin_stream) not served yet 422 unsupported

Spaces and files#

limit value when exceeded
Spaces per account (live and hibernated) your account's cap (above) 429 quota_exceeded
disk per account on the node 50 GiB (51,200 MiB) 507 insufficient_storage, scope: tenant
live Spaces per node (hibernated ones do not count) 400 429 space_limit_reached, retryable
forks per call 1–50 400
labels per Space 32; key [A-Za-z0-9._/-]{1,63}, value ≤ 255 chars 400
name [A-Za-z0-9._-]{1,63}, unique per account 400 / 409 conflict
JSON request body 1 MiB 413
single file upload (PUT /v1/spaces/{id}/files) 512 MiB, streamed 413
archive upload (POST /v1/spaces/{id}/files/archive) 2 GiB 413
Idempotency-Key 1–255 chars, kept 24 h

Secrets, network, terminals#

limit value
secrets per Space 64
secret value size 16 KiB
egress allow entries 256
terminals per Space (shark connect) 8 (429 too_many_terminals)
one-time preview login link 60 s, one use
exposed process idle before it sleeps idle_s, default 30 s

API#

limit value
request rate per credential 100/s, burst 500 (429 rate_limited with Retry-After)
failed authentications per address limited (429 auth_rate_limited)
transport HTTPS only (plain HTTP is refused except on loopback)

Not available (today)#

GPUs; non-Linux guests; process memory carried across commands; the services, snapshots, restore, connectors, model-gateway, events and webhooks routes (422 unsupported); stdin streaming; E2B SDK compatibility. shark connect is coming on the hosted node (exposed processes and preview URLs are live: concepts.md).

<sub>Values: cmd/sharkfs (api_v1*.go, node*.go), internal/apiv1, internal/secrets, and the hosted node's configuration (deploy/v1/shark-api.service) as of 2026-11-05; the account defaults from the account service (control-plane/src/config.ts, DEFAULT_CAPS) as of 2026-11-07. Account quotas can differ per account; GET /v1/quotas tells you yours.</sub>