Skip to main content
Skip to main content

Workspace settings and capacity

A workspace runs every sandbox inside one VM, so the VM's size sets how many sandboxes can run at once. This page explains how the workspace counts its capacity, the workspace policy that caps what a sandbox may ask for, and the domains sandbox ports are published under.

# capacity, usage, domains and the policy of the current workspace
zbox workspace

The console shows the same on its Workspace page, where you can also edit the policy and the domains.

Capacity​

zbox workspace prints the capacity and what is in use, for example on a workspace with 2 CPU cores and 4 GiB of RAM:

Capacity	16 vcpu (2 cores x 8), 3.3 GiB memory (3.8 GiB less 512.0 MiB reserve), 9.9 GiB disk (1.0 GiB headroom)
In use 3 vcpu, 3.0 GiB memory reserved by 3 running sandboxes (0 parked), 274.0 MiB resident, 1.0 GiB disk
ResourceCapacity
vCPUsThe workspace's CPU cores × cpuOvercommit (8 unless the policy sets another value).
MemoryThe VM's memory less a reserve for the workspace's own system (coreReserveBytes, 512 MiB unless the policy sets another value). Memory is never overcommitted.
DiskThe workspace disk. 1 GiB must stay free (the headroom) for anything new to start.

zbox workspace --json and GET /api/rest/workspace answer the same numbers in bytes: capacity holds the usable and the total memory, the reserve, the cores, cpuOvercommit, the disk and the headroom. usage holds what is reserved (cpus, memoryBytes), what the sandboxes hold (memoryResidentBytes), the used disk, the running and parked sandboxes, and the builds in progress.

What a sandbox reserves​

  • A running sandbox reserves its memory size and its vCPUs. The reservation is the size you gave the sandbox, not what it uses: the resident figure shows how much memory the sandboxes actually touch. A sandbox reserves the same while it is being created, woken, restored or parked (CREATING, WAKING, RESTORING, PARKING).
  • A sandbox you remove keeps its reservation while it is TERMINATING, also when it was parked, and frees it when it is TERMINATED.
  • A parked sandbox reserves no CPU and no memory, and neither does a FAILED one. A parked sandbox keeps its disk and, when parked with memory, a memory image on the workspace disk (park and wake).
  • A base pull or a base build reserves 512 MiB of memory while it runs, the memory a build may use (build a base). A warm template build reserves the template's size while it builds (warm templates).
  • A resize of a running sandbox needs only the growth to fit, because the sandbox already holds its old size (resize a sandbox).
  • A disk is a cap, not a reservation. Nothing reserves disk space, every capacity check only wants the headroom free (what uses the disk).

A sandbox can't have more vCPUs than the workspace has cores. vCPUs beyond the cores are shared: the running sandboxes get CPU time in proportion to their vCPUs.

What uses the disk​

Everything a workspace stores sits on its disk: bases, templates (with their memory images when warm), what each sandbox writes to its disk, the memory images of sandboxes parked with memory, snapshots, file exports and uploaded archives for 24 hours, and the cache of base builds. A sandbox's disk takes space only for what the sandbox writes. A fork shares its parent's disk and adds only what changes afterwards (fork a sandbox).

The space a sandbox's disk takes only grows. Deleting files inside the sandbox doesn't give it back to the workspace disk: the sandbox's disk doesn't support discard, so fstrim fails. A parked sandbox keeps its whole disk. Only removing the sandbox frees its disk and memory image.

A full workspace disk breaks every running sandbox

Sandboxes don't reserve disk. Every sandbox sees its disk at its full size even when the workspace has less free space, and the headroom only stops new sandboxes, wakes, forks, restores, snapshots, builds, exports and imports from starting. When the workspace disk does fill up, writes fail with I/O errors in every running sandbox, not just a No space left on device in the one that wrote the most. Keep an eye on the disk line of zbox workspace when sandboxes write a lot.

When the workspace is full​

Creating, forking, restoring, waking or resizing a sandbox, taking a snapshot, building a warm template, pulling or building a base, and exporting or importing a sandbox each check the free capacity first. An export or an import also needs room for the archive it writes, on top of the headroom. If something doesn't fit, the request fails with 409 workspaceFull and the CLI exits with code 7:

error: workspace full: memory 512.0 MiB needed, 235.1 MiB free of 3.3 GiB; park a sandbox or scale the workspace

The error's metadata names the resource (memory, cpu or disk) with requested, free and usable (bytes, or vCPUs for cpu). The workspace never parks or removes sandboxes to make room. To free capacity:

  • memory or CPU: park sandboxes you don't need right now, or remove them (park and wake), or give new sandboxes smaller sizes.
  • disk: remove sandboxes, snapshots, templates, bases and file exports you no longer need, or park sandboxes with --no-memory to drop their memory images (delete bases and templates). Deleting files inside a sandbox doesn't help (what uses the disk).
  • any: resize the workspace. Disk can only grow.

Workspace policy​

The workspace policy sets ceilings for every sandbox and template in the workspace, and the two numbers the capacity is computed from. A new workspace has an empty policy ({}): no ceilings, and the default capacity settings.

FieldWhat it doesWhen not set
allowedNetworkModesThe network modes a sandbox may use, for example ["INTERNET", "AIRGAPPED"].All modes
maxCpusMost vCPUs per sandbox.Up to the workspace's cores
maxMemoryBytesMost memory per sandbox, in bytes.Up to the free capacity
maxDiskBytesLargest disk per sandbox, in bytes.Up to the workspace disk
defaultDiskBytesDisk of a sandbox or template created from a base without a disk size, in bytes. A sandbox from a template takes the template's disk.10 GiB
maxIdleTtlSecondsLongest idle TTL a sandbox may set.No cap
maxAbsoluteTtlSecondsLongest absolute TTL a sandbox may set.No cap
coreReserveBytesMemory kept for the workspace's own system, taken off the usable memory. 0 is allowed.512 MiB
cpuOvercommitvCPUs the running sandboxes may reserve per core, from 1 to 64.8
secrets.allowedModesThe secret modes a sandbox may use, of NONE, ALLOWLIST (a list of names) and ALL_ENVS (--secrets all).All modes
secrets.allowedNamesThe workspace variables a sandbox may select or alias as secrets. With a list, ALL_ENVS is refused.No limit, also when empty

A sandbox or template over a ceiling is refused with 422 policyViolation, for example memoryBytes 1610612736 exceeds the template or Workspace ceiling. The size ceilings are checked on create, on every fork child and restore, on a wake that changes the size, and on import. A change of the name or the TTLs checks the network mode, the TTLs and the secrets again, but not the size, so it passes under a lowered size ceiling. The secrets ceiling is checked on create, on a change of the sandbox policy (PUT /api/rest/sandbox/{id}/policy) and on import (secrets). The TTL caps apply only to TTLs you set: a sandbox without TTLs is always allowed (idle and absolute TTL). A template can set lower ceilings of its own, but none above the workspace's (templates).

Print the policy, edit it and write it back. -f replaces the whole policy, so start from the printed one; - reads it from stdin:

# print the policy as JSON
zbox workspace policy > policy.json
# cap sandboxes at 2 vCPUs and 4 GiB, no project network access, only GH_TOKEN as a secret
cat > policy.json <<'EOF'
{
"maxCpus": 2,
"maxMemoryBytes": 4294967296,
"allowedNetworkModes": ["INTERNET", "AIRGAPPED"],
"secrets": { "allowedNames": ["GH_TOKEN"] }
}
EOF
zbox workspace policy -f policy.json
# back to the defaults
echo '{}' | zbox workspace policy -f -

The console's Workspace page has the same form. The API is PUT /api/rest/workspace/policy (HTTP API).

Changes apply at once to new requests. coreReserveBytes and cpuOvercommit change the capacity immediately. Existing sandboxes keep their size and network mode when you tighten the policy, even if they are now over a ceiling or the running ones reserve more than the new capacity; nothing new is admitted until they fit.

Defaults for new sandboxes​

A sandbox created without these options gets:

SettingDefault
Size1 vCPU, 512 MiB of memory, a disk of the policy's defaultDiskBytes or 10 GiB (sizes)
Network modePROJECT_INTERNET in the CLI and the console (the API requires a mode)
Egress rulesNone, the network mode alone decides (egress rules)
Idle and absolute TTLNone
PortsNone

A sandbox created from a template takes the template's size, ports and egress rules instead (templates). Apart from defaultDiskBytes, the policy has no fields for these defaults: set them per sandbox (create a sandbox) or through a template.

Domains​

Sandbox ports get their public URLs from the workspace's domains. Each HTTP port of a sandbox gets one URL per domain, in the order the domains are listed, so hosts of a sandbox lists every port once per domain. zbox open and the console open the URL on the first domain. With no domain, sandbox ports have no public URL. Who may open a URL is up to the port's access mode.

A domain has one of two forms:

FormURL of port 3000 of sandbox l8mvceq5Use for
dashhttps://3000-l8mvceq5-zbox-6da-8081.prg1.zerops.app/The Zerops subdomain of the workspace's port 8081
dothttps://3000-l8mvceq5.box.example.com/Your own wildcard domain *.box.example.com

The domains are set only through the CLI, the console or the API (PUT /api/rest/workspace/domains). Zerops never adds one on its own.

# list the domains
zbox workspace domain list
# add your own wildcard domain (dot form is the default)
zbox workspace domain add box.example.com
# add the Zerops subdomain of port 8081
zbox workspace domain add zbox-6da-8081.prg1.zerops.app --form dash
# remove a domain
zbox workspace domain remove box.example.com

A domain is a bare lowercase hostname, without *., a scheme or a path. A new domain goes to the end of the list. Removing a domain takes effect at once: every URL on it stops working, including links you have already shared.

Zerops subdomain​

zbox setup turns on subdomain access and adds the subdomain of port 8081 as the first domain, in the dash form. A workspace created in the Zerops GUI or with import YAML starts without a domain. Turn on subdomain access for the service, then add the second URL Zerops shows for it (the one with 8081) without https://:

zbox workspace domain add zbox-6da-8081.prg1.zerops.app --form dash

Your own domain​

To publish sandbox ports under your own domain, for example box.example.com:

  1. In the Zerops GUI, add the domain access for the workspace service with the wildcard domain *.box.example.com and route it to port 8081 of the workspace (public access through your domain).
  2. Point *.box.example.com to the project's IP addresses and add the _acme-challenge CNAME record, so Zerops can issue the wildcard certificate (wildcard domains).
  3. Add the domain to the workspace: zbox workspace domain add box.example.com.

Each sandbox port is then reachable at https://<port>-<sandbox-id>.box.example.com/.

Caution

Without a dedicated IPv4 address, the project's own domains go through the shared IPv4, which closes every connection after about two minutes. WebSockets and long downloads to sandbox ports break for IPv4 clients. Add a dedicated IPv4 to the project if you need them.