fork(n) is Podflare’s core primitive for agent tree-search. Call it on any running sandbox and you instantly get n independent copies, each starting from the parent’s exact state — same Python variables, same imported modules, same files on disk. From that point, every child diverges in complete isolation: memory writes and filesystem writes are copy-on-write, so nothing one child does affects another.
The practical result: you load expensive data once into a parent sandbox, fork N ways to explore N plans in parallel, compare results, and promote the winner — without re-loading data or re-running setup code in each branch.
How to use fork
What each child inherits
Every child starts from a snapshot taken at the moment you calledfork():
| Inherited | Not shared after fork |
|---|---|
| Python REPL state (variables, imports, open file handles, in-memory objects) | Subsequent memory writes (copy-on-write) |
| Filesystem state (all files written to the parent’s rootfs) | Subsequent filesystem writes (copy-on-write) |
| Full process tree (every running process in the VM) | Each child’s vsock connection (independent control channel) |
Children run their REPL and filesystem fully independently. A crash in one child never affects siblings or the parent.
Fork timing
Fork is fast because children boot in parallel and share memory pages until they diverge. Measured on production hardware:| n children | snapshot | rebase | spawn (parallel) | total |
|---|---|---|---|---|
| 1 | 72 ms | 7 ms | 13 ms | 92 ms |
| 2 | 79 ms | 9 ms | 14 ms | 102 ms |
| 5 | 75 ms | 9 ms | 17 ms | 101 ms |
n because all children restore concurrently — adding more children doesn’t proportionally increase total time.
Comparing forks with diff()
Usediff(other) to compare filesystem state between two sandboxes forked from the same parent:
diff() compares /root and /tmp. Pass paths=[...] to compare other directories.
Promoting a winner with merge_into()
Once you’ve identified the best fork, promote it as the parent’s new state:merge_into(winner), the parent sandbox continues with the winner’s memory and filesystem state. The winner’s sandbox ID becomes defunct — use the parent ID going forward.
Limits
- Maximum
n: 32 children perfork()call fork()requires a sandbox created from the API (pool-backed or a previous fork child). Sandboxes created in local dev mode without pool support are not forkable.
Related concepts
Python REPL
How REPL state persists and what fork inherits
Sandboxes
Sandbox lifecycle and isolation guarantees