Sandboxes are secure, isolated containers in Modal that boot in seconds. They provide a flexible execution environment for running arbitrary commands.
Access the Sandboxes API
import { ModalClient } from "modal" ;
const modal = new ModalClient ();
const app = await modal . apps . fromName ( "my-app" , { createIfMissing: true });
const image = modal . images . fromRegistry ( "python:3.13" );
const sandbox = await modal . sandboxes . create ( app , image );
Methods
modal.sandboxes.create(app, image, params?)
Create a new Sandbox in the specified App with the given Image.
The App context for the Sandbox.
The container image to use.
Configuration options CPU reservation in cores (can be fractional).
Memory reservation in MiB.
Memory hard limit in MiB.
GPU configuration (e.g., "A100", "T4:2", "A100-80GB:4").
Maximum lifetime in milliseconds (default: 5 minutes). Must be a multiple of 1000.
Idle timeout in milliseconds. Must be a multiple of 1000.
Working directory (must be an absolute path).
Command to run. Defaults to sleeping indefinitely.
Secrets to inject as environment variables.
Volumes to mount at specified paths.
cloudBucketMounts
Record<string, CloudBucketMount>
Cloud bucket mounts.
Enable a PTY for the Sandbox.
Ports to tunnel with TLS encryption.
Ports to tunnel with HTTP/2.
Ports to tunnel without encryption.
Block all network access.
List of CIDRs to allow. Cannot be used with blockNetwork.
Cloud provider to run on.
Proxy to use for this Sandbox.
Optional name for the Sandbox (unique within an App).
Custom domain for connections (Enterprise only).
The created Sandbox object.
const sandbox = await modal . sandboxes . create ( app , image , {
cpu: 2 ,
memoryMiB: 4096 ,
timeoutMs: 600000 , // 10 minutes
env: { ENVIRONMENT: "production" },
command: [ "python" , "server.py" ],
});
modal.sandboxes.fromId(sandboxId)
Get a running Sandbox by its ID.
const sandbox = await modal . sandboxes . fromId ( "sb-123456" );
modal.sandboxes.fromName(appName, name, params?)
Get a running Sandbox by name from a deployed App.
Name of the deployed App.
const sandbox = await modal . sandboxes . fromName ( "my-app" , "worker-1" );
modal.sandboxes.list(params?)
List all Sandboxes for the current environment or App.
Filter parameters Only return Sandboxes with all specified tags.
An async iterator of Sandbox objects.
for await ( const sandbox of modal . sandboxes . list ()) {
console . log ( sandbox . sandboxId );
}
// Filter by tags
for await ( const sandbox of modal . sandboxes . list ({
tags: { env: "production" }
})) {
console . log ( sandbox . sandboxId );
}
Sandbox object
Properties
Unique identifier for the Sandbox.
Stream for writing to the Sandbox’s standard input.
Stream for reading the Sandbox’s standard output.
Stream for reading the Sandbox’s standard error.
Methods
exec(command, params?)
Execute a command in the Sandbox and return a process handle.
Command and arguments to execute.
Execution options mode
'text' | 'binary'
default: "'text'"
Stream encoding mode.
stdout
'pipe' | 'ignore'
default: "'pipe'"
How to handle stdout.
stderr
'pipe' | 'ignore'
default: "'pipe'"
How to handle stderr.
Working directory for the command.
Timeout in milliseconds. Must be a multiple of 1000.
Additional environment variables.
Enable a PTY for the command.
return
Promise<ContainerProcess>
A process object with stdin, stdout, stderr streams and a wait() method.
// Execute a simple command
const proc = await sandbox . exec ([ "python" , "--version" ]);
const output = await proc . stdout . readText ();
console . log ( output );
const exitCode = await proc . wait ();
// Binary mode
const proc = await sandbox . exec ([ "cat" , "image.png" ], { mode: "binary" });
const imageData = await proc . stdout . readBytes ();
terminate(params?)
Terminate the Sandbox.
Termination options If true, wait for termination and return the exit code.
Returns void by default, or the exit code if wait is true.
// Terminate without waiting
await sandbox . terminate ();
// Terminate and get exit code
const exitCode = await sandbox . terminate ({ wait: true });
console . log ( `Exited with code: ${ exitCode } ` );
wait()
Wait for the Sandbox to finish and return the exit code.
const exitCode = await sandbox . wait ();
poll()
Check if the Sandbox has finished without blocking.
The exit code if finished, or null if still running.
const exitCode = await sandbox . poll ();
if ( exitCode !== null ) {
console . log ( `Finished with code: ${ exitCode } ` );
} else {
console . log ( "Still running" );
}
tunnels(timeoutMs?)
Get tunnel metadata for ports exposed by the Sandbox.
return
Promise<Record<number, Tunnel>>
A mapping of container ports to Tunnel objects.
const sandbox = await modal . sandboxes . create ( app , image , {
encryptedPorts: [ 8000 ],
});
const tunnels = await sandbox . tunnels ();
const tunnel = tunnels [ 8000 ];
console . log ( `Service available at: ${ tunnel . url } ` );
open(path, mode?)
Open a file in the Sandbox filesystem.
mode
SandboxFileMode
default: "'r'"
File mode: "r", "w", "a", "r+", "w+", or "a+".
A file handle with read(), write(), and close() methods.
const file = await sandbox . open ( "/data/output.txt" , "w" );
await file . write ( "Hello, world!" );
await file . close ();
const file = await sandbox . open ( "/data/output.txt" , "r" );
const content = await file . read ();
await file . close ();
snapshotFilesystem(timeoutMs?)
Snapshot the entire filesystem and return an Image.
An Image containing the filesystem snapshot.
const snapshot = await sandbox . snapshotFilesystem ();
console . log ( `Snapshot image ID: ${ snapshot . imageId } ` );
// Use the snapshot to create a new sandbox
const newSandbox = await modal . sandboxes . create ( app , snapshot );
mountImage(path, image?)
Mount an Image at a path in the Sandbox filesystem.
Image to mount. If undefined, mounts an empty directory.
const dataImage = await modal . images . fromId ( "im-123456" );
await sandbox . mountImage ( "/mnt/data" , dataImage );
snapshotDirectory(path)
Snapshot a directory and return an Image.
Directory path to snapshot.
An Image containing the directory contents.
const dirSnapshot = await sandbox . snapshotDirectory ( "/workspace/output" );
Set tags (key-value pairs) on the Sandbox.
tags
Record<string, string>
required
Tags to set.
await sandbox . setTags ({
env: "production" ,
version: "1.0" ,
});
Get tags currently attached to the Sandbox.
return
Promise<Record<string, string>>
The Sandbox’s tags.
const tags = await sandbox . getTags ();
console . log ( tags ); // { env: "production", version: "1.0" }
detach()
Disconnect from the Sandbox, cleaning up local resources. The Sandbox continues running.
Example: Run a Python script
import { ModalClient } from "modal" ;
const modal = new ModalClient ();
const app = await modal . apps . fromName ( "python-runner" , {
createIfMissing: true ,
});
const image = modal . images
. fromRegistry ( "python:3.13" )
. dockerfileCommands ([ "RUN pip install requests numpy" ]);
const sandbox = await modal . sandboxes . create ( app , image , {
memoryMiB: 2048 ,
});
// Write a script
const script = await sandbox . open ( "/tmp/script.py" , "w" );
await script . write ( `
import numpy as np
print(f"NumPy version: {np.__version__}")
print(f"Random array: {np.random.rand(5)}")
` );
await script . close ();
// Execute it
const proc = await sandbox . exec ([ "python" , "/tmp/script.py" ]);
const output = await proc . stdout . readText ();
console . log ( output );
await sandbox . terminate ();
Example: Web server with port tunneling
import { ModalClient } from "modal" ;
const modal = new ModalClient ();
const app = await modal . apps . fromName ( "web-server" , {
createIfMissing: true ,
});
const image = modal . images
. fromRegistry ( "python:3.13" )
. dockerfileCommands ([ "RUN pip install fastapi uvicorn" ]);
const sandbox = await modal . sandboxes . create ( app , image , {
encryptedPorts: [ 8000 ],
command: [
"uvicorn" ,
"main:app" ,
"--host" ,
"0.0.0.0" ,
"--port" ,
"8000" ,
],
});
const tunnels = await sandbox . tunnels ();
const tunnel = tunnels [ 8000 ];
console . log ( `Server available at: ${ tunnel . url } ` );
// Access the server...
await sandbox . terminate ();