Overview
Monty enforces configurable resource limits to prevent untrusted code from consuming excessive resources. Without limits, malicious code could:- Allocate gigabytes of memory
- Run infinite loops
- Cause stack overflow with deep recursion
- Generate massive strings or lists
Available Limits
Monty tracks four types of resource limits:Max Memory
Limit total heap memory usage in bytes
Max Duration
Timeout after specified execution time
Max Allocations
Limit number of heap allocations
Max Recursion Depth
Prevent stack overflow (default: 1000)
Setting Resource Limits
Memory Limit
How It Works
Monty tracks approximate heap memory usage and checks before each allocation:Large Result Pre-checks
Monty pre-checks operations that may produce large results (>100KB) before allocating:The 100KB threshold (
LARGE_RESULT_THRESHOLD) is compile-time and cannot be changed at runtime.What Counts Toward Memory
Time Limit
How It Works
Monty checks elapsed time periodically during execution:Time Check Frequency
Monty checks time every 10 VM instructions to balance:- Performance (checking every instruction is expensive)
- Responsiveness (catching timeouts quickly)
Time is reset after
load() when deserializing execution state. Use tracker_mut() to set a new limit when resuming.Setting Time Limits on Resume
Allocation Limit
How It Works
Counts the total number of heap allocations:When to Use Allocation Limits
Use allocation limits to:- Prevent memory fragmentation
- Control garbage collection frequency
- Limit total number of objects
Recursion Depth Limit
How It Works
Limits the maximum call stack depth:Default Recursion Limit
If not specified, Monty uses 1000 (same as CPython’s default).Platform Considerations
Very deep recursion (>500) may cause stack overflow in debug builds. Release builds handle 1000+ safely.No Limits Mode
For trusted code, useNoLimitTracker to disable limits:
Exception Types
Resource limit violations raise specific Python exceptions:Handling Resource Errors
Garbage Collection
GC Intervals
Configure how often garbage collection runs:When to Adjust GC Interval
- Lower interval (e.g., 100): More frequent GC, lower peak memory
- Higher interval (e.g., 10000): Less GC overhead, higher peak memory
- No interval (
None): Only run GC on allocation failure
Garbage collection only matters for code that creates reference cycles (circular references). Most code doesn’t need GC.
Recommended Limits
For User-Generated Code
For LLM-Generated Code
For Batch Processing
Monitoring Resource Usage
Track resource usage during execution:Resource monitoring APIs are available in the Rust API. Python/TypeScript bindings may be added in future versions.
Best Practices
1
Always Set Limits for Untrusted Code
Never run untrusted code without resource limits. Always configure at least memory and time limits.
2
Set Conservative Limits Initially
Start with strict limits and increase based on actual usage patterns.
3
Monitor and Alert
Log resource limit violations to detect potential attacks or bugs.
4
Adjust Time Limits on Resume
When using iterative execution, set appropriate time limits before each
resume().5
Balance GC Frequency
Adjust
gc_interval based on your memory vs. performance requirements.Next Steps
Security Model
Learn about Monty’s sandbox isolation and security guarantees
Execution Modes
Understand run() vs start()/resume() execution
