The sandbox environment
Every sandbox is a Firecracker microVM with its own Linux kernel and disk, started from the same image. This page says what is in it, who you are inside it, and what it can reach.
What is installed
The image is Ubuntu 24.04.5 LTS (noble) for amd64, on a 6.1 kernel.
| Kind | What |
|---|---|
| Python | Python 3.12 (python3 and python), pip and pip3, venv, and uv 0.12.17 (uv, uvx) |
| JavaScript | Node.js 24.21.0 (node, npm, npx); Bun 1.4.0 (bun) |
| Build | gcc, g++, make (build-essential) |
| Source and fetch | git, curl, wget, ssh, zip, unzip, xz |
| Search and data | rg (ripgrep), fd, jq, sqlite3 |
| System | sudo, chronyd |
Anything else installs the usual way: sudo apt-get install -y ...,
pip install ..., npm install ..., uv pip install .... To start every
sandbox with your dependencies already there, build a custom image.
Java, Go and Rust are not installed. Install Ubuntu's packages with
sudo apt-get install, or a newer release with the language's own installer,
such as rustup for Rust. To have one in every sandbox, build a custom image
whose recipe installs it, or start the image from a public image that already
has it.
Docker is not installed either, and running containers inside a sandbox has not been tested. To start sandboxes from a Dockerfile, build it as a custom image instead; single-stage Dockerfiles are supported.
Browsers are not in the image, because every byte of it counts against each sandbox's disk. For Playwright's Chromium:
Terminalsudo npx playwright install-deps chromiumnpx playwright install chromiumWho you are
- Commands run as the user
runtime(uid 1000), withbash. HOMEis/workspace, which is also the default working directory. Files there belong to you.sudoworks without a password: you are root inside your own sandbox. Root cannot change what the sandbox may reach, how much CPU and memory it has, or what it costs; those are enforced on the host, outside the sandbox.PATHstarts with/workspace/.local/bin, then/usr/local/bin,/usr/binand/bin.LANGisC.UTF-8.
pip install works without a virtual environment. As runtime it installs to
/workspace/.local (whose bin is first on PATH); under sudo it installs to
/usr/local. The image's /etc/pip.conf sets break-system-packages, so the
Ubuntu rule against installing into the system Python (PEP 668) does not stop
you. Use python3 -m venv or uv when you want isolation.
Disk, CPU and memory
The disk you ask for with diskMiB includes the system image, which uses about
1 GiB of it, so the default 4 GiB sandbox has about 3 GiB free; ask for more
when you install a lot. The smallest disk is 3072 MiB, the size of the image
file. Each sandbox's disk reads and writes are limited in speed, to about
40 MB/s and 2,000 operations a second each way whatever the sandbox's size, so
one sandbox cannot swamp the drive it shares with others. CPU is
shared by default, with a guaranteed floor (cpuFloorMillis, 50 thousandths of a
vCPU unless you ask for more) and bursts up to vcpu cores. Memory is what you
ask for. See pricing for what each costs.
The network
A sandbox has no network card. Everything outbound goes through a proxy on the host, and the image sets the environment every tool needs to find it:
textHTTP_PROXY=http://127.0.0.1:10800 http_proxy=http://127.0.0.1:10800HTTPS_PROXY=http://127.0.0.1:10800 https_proxy=http://127.0.0.1:10800NO_PROXY=localhost,127.0.0.1,::1 NODE_USE_ENV_PROXY=1sudo keeps these. A program that ignores proxy settings and opens raw sockets
does not reach the internet.
By default a sandbox reaches the public web on ports 443 and 80. Private and internal addresses are refused. Mail ports (25, 465 and 587) are closed unless support enables them for your account, and a few ports are never reachable: telnet, Windows RPC, NetBIOS and SMB, and IRC.
Each sandbox has its own rules, set at create (network) or at any time after,
applied at once, to open connections too:
TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ network: { internet: true, allow: ["pypi.org", "*.pythonhosted.org"] },});await sbx.network.set({ internet: true, deny: ["example.com"] });await sbx.network.set({ internet: false });console.log(await sbx.network.get());internet: falserefuses every outbound connection.allownarrows the web to a list: domains,*.domainfor every name under one, addresses or CIDR ranges.denyalways wins.connectopenshost:portpairs beyond the web ports, such as your own database orgithub.com:22, for paid sandboxes of accounts that have made a purchase. Inside the sandbox,python3 /usr/local/lib/runtime/guest-egress.py forward 5432 db.example.com:5432gives a program a local port to use.
The rules apply to root inside the sandbox too.
Nothing can connect in to a sandbox except through a preview: an HTTPS address
for one port that you share on purpose, private with a token by default. See
JavaScript or npx withruntime sandbox preview. A sandbox
with no preview accepts no incoming connections.
Time and lifetime
The clock is kept on the host's clock, and set again after every wake. A sandbox
runs until its lease ends (timeoutSeconds, at most an hour ahead, which
extend moves), then pauses or stops as onLeaseEnd says. A host-side lease
bounds execution even if management is unavailable. A stopped sandbox is not a
backup; copy out what you need to keep.