Skip to main content
This page lists what each plan allows, the machine specs, and the limits you can run into inside a machine. Your own limits and counts are in instabox usage, on Account in the dashboard, and in GET /v1/usage.
  • Over the machine or storage limit, new machines and snapshots are refused until you delete some. Account warns from 80% of your storage.
  • A machine started from a snapshot has at least the storage of the machine it was saved from.

Machine specs

Every template but ci (Ubuntu 24.04) and omarchy (Arch Linux) is Debian 13 (trixie), amd64, with systemd, on Linux 6.18.60 (uname -r: 6.18.60-instabox; 6.18.60-instabox-android on android, 6.18.60-instabox-drm on omarchy) in a Firecracker microVM. A machine is by default (free -m shows about 7.8 GiB on that size) with a GiB persistent ext4 disk at /data (home is /data/home). Every template but omarchy has git, curl, jq, Python with venv and pip, and passwordless sudo with apt; omarchy has git, curl, jq, Arch’s Python, and passwordless sudo with pacman. The free plan creates from only. To check a machine, run uname -r, cat /etc/os-release, nproc, free -m, and df -h / /data.

Preinstalled tool versions

The ci template’s versions are in CI. To check a tool in a machine, run its own version command, for example claude --version. dpkg -l lists the apt packages.

Inside a machine

GNU time, rg (ripgrep) and htpasswd are not preinstalled on every template. The image ships without apt lists, so apt-get install alone fails until apt-get update has run:
To run another image, such as node:16-buster, use Docker. On agent-browser, universal, and t3, the machine’s user is in group docker, so docker run --rm node:16-buster node -v works without sudo.
On every template but ci and omarchy, npm’s global prefix is /opt/npm, owned by the machine’s user: npm install -g <package> (and claude update) needs no sudo. Do not use sudo npm install -g: it leaves root-owned files that make the next install fail.On agent-browser, universal, and t3, /data belongs to the machine’s user (build in /data/workspace or a new /data/<dir>), and so does the Rust toolchain in /opt/rust. rustup toolchain install, rustup default, and rustup target add need no sudo. A rustup of your own in ~/.cargo takes over cargo and rustc. The JDK is OpenJDK 21 (Debian 13 has no 17), with JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 set for exec and non-interactive SSH.A machine on an older template version (stat -c %U /opt/rust prints root) needs sudo chown -R "$USER": /opt/rust && sudo chown "$USER": /data and sudo apt-get update && sudo apt-get install -y zip openjdk-21-jdk-headless for the same setup.
Without --stream, the output arrives when the command exits, each stream cut at 1 MiB. exec --stream prints the output as it is written, with no cap. A command runs at most 10 minutes (--timeout, 60 seconds by default). A longer job runs with exec --background, which has no exec timeout, though idle pause and max-run still apply. jobs ls|logs|wait|kill follow the job.exec returns when the command exits, even if it started a server in the background. Redirect both streams (nohup ./server >server.log 2>&1 &): a background process still writing to exec’s output gets a broken pipe and may die.
/tmp is a RAM-backed tmpfs capped at a quarter of the machine’s memory. Past the cap a write fails with No space left on device even when df -h /data shows free space. Login shells (SSH, the dashboard terminal, instabox exec) set TMPDIR=/data/tmp, on the persistent disk, so most tools put temporary files there. Files in /data/tmp unused for 10 days are deleted. /dev/shm is tmpfs too.On an older machine (echo $TMPDIR prints nothing), /tmp is about half the memory and temporary files go to memory. Run export TMPDIR="$HOME/tmp" && mkdir -p "$TMPDIR", and add the line to ~/.bashrc.
Each instabox exec is a new shell that starts at 1024 again and does not read ~/.bashrc. For every session, put the ulimit -n line in /etc/profile.d/nofile.sh (or use /etc/security/limits.d/), and the sysctls in /etc/sysctl.d/.
When processes use more memory than the machine and its swap have, the kernel OOM killer kills one. The machine stays running. instabox get shows OOM kills, and an exec whose command was killed returns oomKilled: true. Its exit code is usually 137, but check oomKilled, not signal. An absent or 0 OOM kills does not prove there was none. Confirm inside the machine with dmesg -T | grep -i oom.Every machine has a swapfile, /data/swapfile, the size of its memory up to 4 GiB (and at most a quarter of /data), made at first boot when /data has room. free -h and swapon --show show it. To change its size:
sudo touch /etc/instabox/no-swap keeps swap off. A snapshot or fork carries the swapfile, which can hold paged-out secrets. Before sharing a snapshot, zero the swapfile (sudo swapoff /data/swapfile && sudo shred -n0 -z /data/swapfile && sudo mkswap /data/swapfile && sudo swapon /data/swapfile) or save --root-only. For a machine that keeps running out, raise its size or its swap.
What a machine sends is capped at about 50 Mbit/s (~6 MB/s) with little or no burst. The cap covers uploads, what the machine sends over SSH and port forwards, and responses from its public URLs. A ~100 MB file out takes 15–20 seconds, so keep large artifacts in the machine (on /data, or in a snapshot). What a machine receives is not limited. Report a slow download with instabox feedback. The cap is per machine, separate from your plan’s monthly egress.

Disks, snapshots, and templates

A machine has one disk you size, /data. At create, the disk comes with the machine’s size, and any other disk size is 400 spec_not_allowed. To change it later:
You can also send PATCH /v1/machines/{id} with {"persistentDiskGiB": 50}, or use Resize disk in the machine’s Settings.
  • Paid plans only. A free machine’s disk is fixed at GiB. The disk grows to , within your stored-data limit (429 quota_exceeded). The API takes 1–1024 GiB.
  • Grow: a running machine’s disk grows at once, with no restart. If it cannot grow online, the answer is 409 grow_needs_stop. Stop the machine and send the size again.
  • Shrink: only a stopped machine. Your data plus 10% (at least 1 GiB) must fit, or 409 disk_too_small names the smallest size that does.
  • The REST field is persistentDiskGiB. diskGiB (the TypeScript SDK’s name) is 400 unknown_field in a REST body.
  • The system disk is sized by the template and is not counted. Disk beyond the plan’s included disk is billed: Pricing.
instabox create --snapshot (or Sandbox.create(snapshotId)) without --vcpus or --mem-mib uses your plan’s default size, not the source machine’s. instabox fork keeps the source size. In snapshot JSON, rootSizeBytes and dataSizeBytes are the logical disk sizes the next create provisions, not the bytes stored.
instabox templates (GET /v1/templates) lists what you can create from. A version no host holds any more is creatable: false, and a create pinned to it is 400 bad_request (not retryable). An older pin such as agent-browser@2026-10-08.2 is held by fewer hosts, so it can fail with no_capacity while latest creates at once. Prefer an unpinned template unless you need the pin.

Pricing

Plans and unit prices.

Errors

quota_exceeded, rate_limited, spec_not_allowed and the rest.