Modal logo

Sandbox Exit Snapshots

Exit Snapshots take a filesystem snapshot automatically on both graceful and ungraceful Sandbox exits, including terminate(), entrypoint completion, idle timeout, lifetime expiry, and OOM.

This is useful when you want filesystem state after a Sandbox is gone without having to snapshot the filesystem yourself first. Typical uses:

  • Resuming an agent or coding session after an idle timeout
  • Recovering work from a Sandbox that exited unexpectedly
  • Avoiding races between your own teardown and an in-flight manual snapshot

Usage 

Opt in at time of creation by setting enable_exit_snapshot in the experimental options, then fetch the resulting Image after the Sandbox has exited:

import modal

app = modal.App.lookup("exit-snapshot-example", create_if_missing=True)

sb = modal.Sandbox.create(
    "bash",
    "-c",
    "echo hello > /tmp/marker.txt",
    app=app,
    experimental_options={"enable_exit_snapshot": True},
)
sb.wait()

image = sb._experimental_get_exit_snapshot()
restored = modal.Sandbox.create(app=app, image=image)
print(restored.filesystem.read_text("/tmp/marker.txt"))  # "hello\n"
restored.terminate()

You can also reconnect to the Sandbox later by ID and fetch the exit snapshot from that handle. This is useful when the create and resume happen in different processes:

import modal

app = modal.App.lookup("exit-snapshot-example", create_if_missing=True)

# Process A: create a Sandbox, do work, then let it idle out or terminate.
sb = modal.Sandbox.create(
    app=app,
    experimental_options={"enable_exit_snapshot": True},
)
sb.filesystem.write_text("session state", "/workspace/state.txt")
sandbox_id = sb.object_id
sb.terminate(wait=True)

# Process B: resume from the exit snapshot.
sb = modal.Sandbox.from_id(sandbox_id)
image = sb._experimental_get_exit_snapshot()
sb2 = modal.Sandbox.create(app=app, image=image)
print(sb2.filesystem.read_text("/workspace/state.txt"))  # "session state"
sb2.terminate()

Waiting for the snapshot 

Fetching the exit snapshot long-polls until the snapshot reaches a terminal state. The timeout parameter controls how long to wait:

TimeoutBehavior
Unset (default)Wait until the snapshot succeeds or fails
0Immediate check; fails with TimeoutError if pending
> 0Wait up to the specified duration

On success, the method returns an Image you can use to create a new Sandbox.

Errors 

Fetching the exit snapshot can fail with these errors:

ErrorWhen
SnapshotCreationErrorSnapshot creation failed
TimeoutErrorStill pending when your timeout elapses
InvalidErrorExit snapshots were not enabled on the Sandbox, or the timeout is negative
NotFoundErrorThe Sandbox no longer exists

In Python these are all modal.exception classes. Note that TimeoutError is Modal’s own class rather than Python’s builtin, so a bare except TimeoutError will not catch it.

Retention 

Exit snapshot Images are retained for 30 days after creation, matching the default for filesystem snapshots. After that, attempting to use the Image fails with NotFoundError.

Limitations 

  • Filesystem only. Exit Snapshots capture the Sandbox filesystem, not memory or directory mounts.
  • Main container only. Sidecar containers are not included.
  • Preemption is not covered. GPU Sandboxes may run on preemptible capacity, and a preempted host generally does not give the Sandbox enough time to take an exit snapshot. This only affects GPU Sandboxes - CPU Sandboxes are not preemptible. If you rely on exit snapshots for GPU Sandboxes, also snapshot the filesystem periodically.
  • Snapshot failure loses that Sandbox’s filesystem state. If you need to periodically persist state with stronger durability guarantees, prefer Volumes.