Sandboxes
Sandboxes are ephemeral remote Linux environments attached to a Railway project + environment. Use them when the user asks for a sandbox, a scratch/ephemeral environment, or wants to build or run something remotely without touching deployed services. Sandboxes link at the project level — a linked project and environment (or explicit --project / --environment flags) is enough; no service link is needed.
Availability — Priority Boarding required
Sandboxes must be enabled in Priority Boarding. If sandbox commands fail with a feature-availability error from the API (the PROJECT_SANDBOXES feature is not enabled for the workspace), do not retry — prompt the user to enable Sandboxes through Priority Boarding in the Railway dashboard, then resume once they confirm.
Two non-errors to expect:
- Every sandbox command prints
Warning: Railway sandboxes are experimental and APIs may change or break during testing.on stderr. This is informational — not a failure. - Context errors (
No project selected.../No environment selected...) mean missing linking, not missing access: runrailway linkor pass--projectand--environment.
Create and connect
Create a sandbox
railway sandbox create
railway sandbox create --variable DB_URL=postgres.DATABASE_URL --env-file .env
railway sandbox create --private-network --idle-timeout-minutes 60 --jsoncreate boots a sandbox and remembers it as the active sandbox — later commands that take --id default to it. --variable values may reference other Railway variables (postgres.DATABASE_URL or the full ${{postgres.DATABASE_URL}} form), resolved server-side at create time; --variable overrides --env-file entries with the same key. Sandboxes are isolated with public egress by default — pass --private-network when the sandbox must reach internal hosts like postgres.railway.internal. --idle-timeout-minutes auto-destroys the sandbox after that long idle; attached sessions send a heartbeat that keeps it alive. Prefer --json for parsing the created id.
Connect over SSH
railway sandbox ssh # interactive shell in the active sandbox
railway sandbox ssh --id <sandbox-id> -- ls -laTrailing -- <command> runs a single command instead of an interactive shell. --session <name> resumes a durable session by name.
Run commands remotely
One-off commands
railway sandbox exec -- npm test
railway sandbox exec --id <sandbox-id> --timeout 120 -- ./integration.shEverything after -- is the command. A single argument runs as a shell command; multiple arguments run as argv with quoting preserved. --timeout <seconds> is a client-side deadline — on expiry the command is terminated and the CLI exits 124 (GNU timeout convention), so treat exit 124 as "took too long", not "failed".
Long-running commands — detach and reattach
railway sandbox exec --detach -- npm run build # prints a durable session name, exits
railway sandbox exec --session <name> # reattach and stream the output--detach starts the command, prints its durable session name to stdout, and returns while the command keeps running — use it for builds or jobs longer than you want to block on. Reattach with --session <name>; add --resume-from-last-read to skip replaying retained scrollback. Durable sessions are not available on every sandbox — when the CLI warns durable sessions are unavailable for this sandbox; ran attached, the command still ran, just without reattach support.
Remote builds
Use templates to run build steps remotely. Build steps execute server-side in a transient sandbox; the result is a content-addressed filesystem snapshot cached server-side, so re-running the same recipe is an instant cache hit.
Build remotely
railway sandbox template build --name ci -c 'npm ci' -c 'npm run build' --wait-c is repeatable and runs in order; each step must exit 0 within 10 minutes. --wait polls until READY or FAILED. --name is a local-only handle for reuse.
Boot from the build
railway sandbox create --template ci # boots from the cached snapshot
railway sandbox exec -- npm startTemplate recipes are stored locally by this CLI — Unknown template means it was built elsewhere or never built; rebuild it with the command the error message prints. For state that must be reachable from other machines or later sessions, capture a checkpoint instead.
Agents in sandboxes
Use sandboxes for agent runs that need isolated compute, private networking to Railway resources, or remote build/test execution. Copy or generate code in the sandbox, run the agent or test command with sandbox exec, and capture a checkpoint if the state should be reused across machines. Prefer --private-network when the agent needs internal service or database access.
Inspect templates
railway sandbox template status <id-or-name> --json
railway sandbox template list --jsonPort forwarding
railway sandbox forward 3000 # localhost:3000 → sandbox port 3000
railway sandbox forward 8080:3000 5432 # explicit local port; multiple ports per connectionIf a requested local port is busy the CLI picks a nearby free one and says so — pass --strict to fail instead. The tunnel auto-reconnects with backoff if the relay drops while the sandbox is still running.
Fork a sandbox
railway sandbox fork # fork the active sandbox; the fork becomes active
railway sandbox fork <sandbox-id> --variable FOO=bar --private-networkA fork copies the source's filesystem state but does not inherit its variables or network mode — re-pass --variable/--env-file/--private-network as needed.
Checkpoints — save and restore sandbox state
Checkpoints are named disk snapshots captured from a running sandbox, stored server-side per environment. Use them to set a sandbox up once (clone a repo, install dependencies, seed data) and boot fresh sandboxes from that state later. Pick the right state mechanism:
- Template: a reproducible recipe built from shell instructions — deterministic, but stored in this CLI's local store, so it only resolves on the machine that built it.
- Fork: a live copy of a sandbox made right now.
- Checkpoint: state you set up interactively, saved server-side by name — works from any machine or later agent session.
Capture
railway sandbox checkpoint create my-setup # capture the active sandbox's disk
railway sandbox checkpoint create my-setup --id <sandbox-id> --jsonCapture is synchronous — the checkpoint is bootable as soon as the command returns, but flushing and uploading a large disk can take a while (the request honors RAILWAY_HTTP_TIMEOUT, so raise that rather than assuming a hang). Reusing a name replaces the previous checkpoint without warning — run checkpoint list first if overwriting matters. 64-character hex names are reserved for template hashes.
Boot from a checkpoint
railway sandbox create --checkpoint my-setup
railway sandbox exec -- npm start--checkpoint and --template are mutually exclusive. A checkpoint restores disk state only — variables and network mode are not part of the snapshot, so re-pass --variable/--env-file/--private-network on create as needed.
Manage checkpoints
railway sandbox checkpoint list --json
railway sandbox checkpoint rename <name> <new-name>
railway sandbox checkpoint delete <name>Checkpoints are scoped to the environment: list shows only the linked environment's checkpoints, and --checkpoint resolves names within that scope. Deleting a checkpoint removes its underlying disk snapshot.
List and teardown
railway sandbox list --json # also refreshes the local id cache
railway sandbox list --all # include destroyed sandboxes
railway sandbox destroy # destroy the active sandbox
railway sandbox destroy <sandbox-id>Destroy sandboxes you created for a task once the task is done — idle timeout is the backstop, not the cleanup plan.
Troubleshoot sandboxes
- Feature-availability error from the API: Sandboxes aren't enabled for this workspace. Prompt the user to enable Sandboxes through Priority Boarding in the Railway dashboard; don't retry until they confirm.
No project selected/No environment selected: runrailway linkor pass--projectwith--environment.Unknown template ...: the recipe isn't in this CLI's local store — rebuild withrailway sandbox template build --name <name> -c '<command>' --wait, or use a checkpoint if the state was meant to travel between machines.Template build failed: a step exited non-zero or exceeded its 10-minute limit; fix that step and rebuild.No checkpoint named ...: checkpoints are environment-scoped — confirm the linked environment and runrailway sandbox checkpoint list; the checkpoint may live in another environment or have been deleted/replaced.- Checkpoint capture times out: a large disk is still uploading — raise
RAILWAY_HTTP_TIMEOUT(seconds) and retry rather than treating it as a failure. - Exit code 124 from
exec: the client-side--timeoutexpired — rerun with a larger timeout or--detach. that session may have expired; the server started a fresh one instead: the durable session lapsed; the command ran in a new session — check whether prior state mattered.- SSH/forward drops: the CLI reconnects automatically while the sandbox is RUNNING; if it reports the sandbox STOPPED, create or fork a new one.
Validated against
- Docs: sandboxes.md, sandbox.md, agents-in-sandboxes.md
- CLI source: sandbox.rs, sandbox_exec.rs