One line of code, one fresh VM:

echo 'print(6*7)' | kedge eval python3

kedge eval <runtime> runs stdin in a fresh VM, streams stdout and stderr, and exits with the code's status. The VM is destroyed afterward; nothing is deployed or persisted.

Each run has the same hardware isolation as an app instance. See instant sandboxes & scale-out for restore latency.

runtimes

runtime interpreter
python3 Python 3.12
node20 Node.js 20
ruby Ruby 3.3
bash Bash
deno Deno, TypeScript

Every image also carries the handler runtime tools: sqlite3, jq, curl, and uptime. A run gets 256 MiB of memory and 30 seconds; the REST eval operation takes a timeout override.

network access

Sandboxes have outbound network access by default. -no-network on kedge eval or kedge sandbox leaves the VM with only a loopback interface. Anonymous runs, including the front-page console, are always networkless regardless of what the request asks for.

interactive sandboxes

kedge sandbox python3 drops you into a shell inside a fresh VM, and kedge shell - does the same without naming a runtime. The VM is destroyed when you exit.

held sandboxes

To run several commands against one VM, open a sandbox and address it by ID:

id=$(curl -sX POST https://kedge.dev/api/sandboxes \
  -H "Authorization: Bearer $KEDGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"runtime":"node20"}' | jq -r .id)

curl -sX POST "https://kedge.dev/api/sandboxes/$id/exec" \
  -H "Authorization: Bearer $KEDGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cmd":["node","-v"]}'

curl -sX DELETE "https://kedge.dev/api/sandboxes/$id" \
  -H "Authorization: Bearer $KEDGE_TOKEN"

A sandbox expires 5 minutes after its last command; ttl_seconds at creation sets a different deadline, up to an hour. One command is capped at 10 minutes, and an account can hold only so many at once: past the cap a create fails with a limit error rather than queuing. Expiry destroys the VM, so a forgotten ID costs nothing.

An ID names the host holding the sandbox, so any node in the fleet answers a call for it and GET /api/sandboxes lists your sandboxes fleet-wide. The VM lives in that host's memory, so it does not survive that host's restart.

POST /api/eval and POST /api/sandbox/exec stay the shorthand when one command is the whole job: they create, run, and destroy in a single call and leave no identifier behind.

A sandbox has no ingress, and its disk is gone when it expires. Persistent interactive work belongs in a workspace, which keeps its full writable filesystem. GitHub Actions runners apply the same one-run boundary to CI jobs.