Skip to main content
Use run() for everyday work, the argv form (run(["cmd", arg])) the moment any part of the command comes from untrusted input, session() when state must carry over, and background=True for servers and workers (the idle policy sees them and keeps the sandbox awake while they live).

Sessions vs. background

They answer different questions. A session keeps state between commands: one shell process stays alive across .run() calls, so cd, export, an activated venv, and shell functions carry over — exactly like a terminal window you keep typing into. Filesystem changes persist either way; it is only process-local state (cwd, environment, shell internals) that dies with each plain run()’s fresh shell. background=True changes one process’s lifetime: the call returns immediately and the process outlives it. They compose — launch a background job from inside a session and keep working.

Sharp edges

A synchronous call has ~110 s at the edge — longer work belongs in background=True or a session, collected later. One argv string caps at 128 KiB (kernel limit). stdout/stderr are UTF-8 text capped at 16 MiB per stream (ExecResult.truncated + an inline notice mark a cut) — big or binary output goes to a file. Background execs return no pid — record one yourself (cmd & echo $! > pid) and redirect output to a file or it is discarded.