Documentation Index
Fetch the complete documentation index at: https://docs.podflare.ai/llms.txt
Use this file to discover all available pages before exploring further.
The model
Each Podflare sandbox runs a long-lived Python process (Python 3.12). Everyrun_code(lang="python") you issue sends a block of code to that
process’s REPL. Execution is in a shared globals dict — so setting a
variable in one call makes it visible to the next.
What persists
- Named values (
x = 1,df = pd.read_csv(...)) - Imported modules (
import pandas as pd) - Open file handles, sockets, threads, subprocesses
- Changes to
sys.path, environment, CWD - Anything else you’d expect to live in Python process memory
What does not persist
- bash
run_codecalls. Shell history and$X=foodo NOT carry over — each bash call is a fresh subprocess. This is intentional; shells are not the right abstraction for long-lived state. - Child processes you start via
subprocess.run. They run, exit, gone. Usesubprocess.Popenif you want a long-lived child.
Fork inherits REPL state
This is the reason we built REPL persistence. When youfork(n), each
child starts from the parent’s exact Python process state.
Exception isolation
A raised exception in onerun_code call doesn’t poison the REPL:
SystemExit is caught too — its code becomes the call’s exit code, not
a hostd crash.
The protocol
The agent and the in-VM Python process communicate over stdin/stdout with a minimal framed protocol:stdout/stderr/exit). See
agent/repl.py
for the runner (compiled into the agent via include_str!).
Serialization
Only onerun_code executes at a time per sandbox. Concurrent calls
serialize via a mutex. If you need parallelism, fork(n) — each child
has its own REPL and you can run them in parallel.
