Monty
A minimal, secure Python 3.14 interpreter written in Rust for use by AI.
Monty avoids the latency, complexity and cost of using a full container based sandbox for running LLM generated code.
| Sandbox | Cold start | Agent run, warm† | Combined‡ |
|---|---|---|---|
| Monty | 4.50 ms | 0.40 ms | 4.90 ms |
| Full Monty (WebSocket) | 3.50 ms | 3.90 ms | 7.40 ms |
| WASI / wasmtime | 16 ms | 180 ms | 200 ms |
| Docker | 195 ms | 700 ms | 900 ms |
| Sandboxing service (Daytona) | 1500 ms | 400 ms | 1900 ms |
| Pyodide in Deno | 2700 ms | 35 ms | 2700 ms |
† 10 commands run in a REPL against a sandbox that already exists, as you might expect from a simple agent with code mode. Monty and Full Monty keep the session, so each command is one feed; the others have no persistent interpreter, so command n re-runs commands 1 to n.
‡ The time to create the sandbox and perform the agent run: the two columns added together.
Learn more in the comparison to alternatives.
- Latency in microseconds, not seconds. A sandbox plus ten REPL commands takes 5 ms against 900 ms for Docker and 1900 ms for a sandboxing service, because the sandbox is a subprocess, a command is one message each way, and the session persists so nothing is re-run. See start latency.
- Suspend and resume from bytes. Every host call suspends the interpreter;
feed_startreturns the suspension anddump()serialises the whole interpreter, paused call stack included, to bytes you can store andload_snapshotlater on another machine. There are no file descriptors, sockets or threads inside the sandbox, so nothing has to be reconstructed. See snapshots. - Strict resource limits
max_memory,max_duration_secsandmax_recursion_depthare enforced by the VM itself, andmax_suspensionsby the pool;'x' * 10**12raisesMemoryErrorbefore the allocation is attempted. See resource limits. - A package, not infrastructure.
uv add pydantic-monty,npm install @pydantic/montyorcargo add monty-pool: about 4.5 MB, no daemon, no image, no API key, and a worker baseline of about 2 MB so one machine runs hundreds. See getting started. - MIT licensed, with commercial options. The interpreter, the pool and bindings are open source. Full Monty runs the same workers behind a WebSocket as a container image, adding OS-level isolation, and horizontal scaling.
Installation
uv add pydantic-monty
npm install @pydantic/monty
cargo add monty-pool
The code string is what a model writes when asked how long a bar of chocolate could power a lightbulb.
It calls a tool it was given, does arithmetic it should not do in its head, and prints the answer:
from pydantic_monty import Monty
code = """
kcal = nutrition('chocolate bar')['kcal']
hours = kcal * 4184 / (bulb_watts * 3600)
print(f'a chocolate bar could power a {bulb_watts}W bulb for {hours:.1f} hours')
"""
with Monty() as pool:
with pool.checkout() as session:
session.feed_run(
code,
inputs={'bulb_watts': 10},
external_lookup={'nutrition': lambda food: {'kcal': 230}},
)
#> a chocolate bar could power a 10W bulb for 26.7 hours
Or in TypeScript:
import { Monty } from '@pydantic/monty'
const code = `
kcal = nutrition('chocolate bar')['kcal']
hours = kcal * 4184 / (bulb_watts * 3600)
print(f'a chocolate bar could power a {bulb_watts}W bulb for {hours:.1f} hours')
`
await using pool = await Monty.create()
await using session = await pool.checkout()
await session.feedRun(code, {
inputs: { bulb_watts: 10 },
externalLookup: { nutrition: (food: string) => ({ kcal: 230 }) },
})
// a chocolate bar could power a 10W bulb for 26.7 hours
nutrition ran on the host and the sandbox saw only its return value; the sandbox has no filesystem, environment or
network with which to reach anything else.
The Python, JavaScript and Rust quickstarts
take it from here.
Monty can do much more than this, see Examples.
LLMs are often faster, cheaper and more reliable when they write a short program that calls your tools, instead of making a sequence of individual tool calls: code mode from Cloudflare, programmatic tool calling and code execution with MCP from Anthropic, smolagents from Hugging Face. All of them need somewhere safe to run the generated code, and Monty is that place.
- Getting started with Python, JavaScript or Rust.
- Commercial support: Full Monty, the same workers behind a WebSocket as a container image.
- Security model for what “secure” does and does not mean here.
- Examples, including Code Mode in Pydantic AI.
- Limitations: the Python subset, and every known divergence from CPython.