Fly.io vs Modal: Agent Sandboxes, Snapshots, and Isolation Compared

Fly.io vs Modal: Agent Sandboxes, Snapshots, and Isolation Compared

Published

Fly.io Sprites are the better platform for agent workloads that have to still be there tomorrow: no duration cap, a filesystem with no expiry, and hardware isolation on every Sprite. Modal is the better tool in one narrow case, which is GPU work.

Modal Sandboxes and Fly.io Sprites both run untrusted, agent-generated code in an isolated Linux environment, and they answer that problem in opposite directions. A Modal Sandbox is a unit of compute with a clock on it: five minutes by default, 24 hours at most,[1] and work survives only if you write a snapshot that later boots as a different sandbox.[2] A Fly.io Sprite is a computer: no duration cap, a 100 GB filesystem that does not expire, supervised services that restart on their own, and a public HTTPS URL that wakes the Sprite when a request arrives. If your agent has to pick up where it left off, that is the entire comparison.

Key takeaways

  • Modal Sandboxes default to a five minute maximum lifetime and can be configured up to 24 hours.[1] Fly.io Sprites have no duration cap of any kind.
  • Modal memory snapshots expire seven days after creation and the limit cannot currently be extended. Restoring one does not resume your sandbox, it creates a new one with a new identity.[2] Fly.io checkpoints restore the same Sprite in place and do not expire.
  • Modal Sandboxes run on gVisor by default, a user-space kernel shared with other tenants.[3] A full VM runtime exists but is in beta.[4] Every Fly.io Sprite is a Firecracker microVM with its own kernel, on every tier.
  • Modal is the right answer when an agent has to train or serve a model in the same environment it writes code in. For everything else, a Sprite is the closer match to what agents actually need.

Fly.io Sprites vs Modal Sandboxes at a glance

Dimension Fly.io Sprites Modal Sandboxes
Isolation Firecracker microVM, every Sprite gVisor by default, full VM runtime in beta
Maximum lifetime No duration cap 5 minutes by default, 24 hours maximum
Filesystem after stop 100 GB of ext4, persists, no expiry Snapshot required, 30 day default TTL
Memory and process state Suspend snapshots RAM, resumes in place Memory snapshots, 7 day cap, not extendable
What restore gives you The same Sprite, same identity A new sandbox cloned from the snapshot
Public address One HTTPS URL per Sprite, wakes on request Tunnel with a random public URL while running
Long-lived processes Supervised services with auto-restart Process state only through memory snapshots
Credentials Connectors broker OAuth outside the Sprite Secrets injected as environment variables
GPUs Not attached to a Sprite Yes

Modal column from Modal’s own documentation: [1] [2] [3] [4] [5] [6]. Checked 2026-09-11.

What is Modal?

Modal is a serverless compute platform built primarily around Python, best known for running functions and batch jobs on demand with fast cold starts. Modal Sandboxes are its primitive for executing untrusted code: you call modal.Sandbox.create(), get a container, run commands in it, and tear it down. Sandboxes inherit Modal’s job-shaped model, including an idle_timeout and a maximum lifetime that defaults to five minutes and can be raised to 24 hours. For runs longer than that, Modal’s own documentation points you at filesystem snapshots to carry state forward rather than at a longer-lived sandbox.[1]

What are Fly.io Sprites?

A Fly.io Sprite is a persistent Linux computer for an agent. It boots as a Firecracker microVM, keeps 100 GB of ext4 that does not expire, and stays addressable at its own HTTPS URL with automatic TLS. Inside, a supervisor runs long-lived programs as services with dependency ordering and automatic restart, so a dev server or a queue worker survives crashes and reboots. When a Sprite goes idle it suspends, and the next request or command brings it back in about a second with its memory intact. The image ships with Claude Code, Cursor CLI, Gemini CLI, and Codex CLI already installed, alongside Node, Python, Go, Ruby, Rust, Java, and Elixir. Fly.io has compared Sprites with Daytona and Cloudflare’s Sandbox SDK as well.

Does the filesystem survive?

Both platforms can keep files. The difference is whether keeping them is the default or a task you have to remember.

Modal gives you three ways to persist state, and each one is an explicit act with a clock attached. Filesystem snapshots capture the whole filesystem and default to 30 day retention, configurable, and can be set to never expire. Directory snapshots do the same for one directory on the same default. Memory snapshots capture filesystem and RAM together and expire seven days after creation, a limit Modal documents as not currently extendable.[2] Volumes are the durable option if you mount one, but a bare Modal Sandbox writes to a filesystem that is gone when the sandbox terminates.

A Sprite gets 100 GB of ext4. It does not expire, it is not a volume you attach, and it is not a tmpfs that happens to survive. The storage layer underneath it, which we call SBD, presents an S3 bucket to the kernel as a block device and runs ordinary ext4 on top, so there is no metadata database to keep consistent and checkpoints are block-level snapshots with copy-on-write clones. Nothing has to be snapshotted for a file to be there next week. Checkpoints exist on top of that as deliberate save points, taken by hand or automatically after an hour of continuous activity, on idle, and at graceful shutdown, with tiered retention so you keep a usable history without managing it. Checkpoints do not rot and there is no countdown to turn off.

The practical version: on Modal, the default outcome of walking away is that your work expires. On Fly.io, the default outcome of walking away is that your work is still there.

Do the processes survive?

Modal’s answer is memory snapshots, which capture every running process and restore them in the same state. It works, within its limitations.[2] A snapshot must be restored on an identical instance type. GPUs are not supported. The sandbox terminates while the snapshot is taken. You cannot snapshot while an exec command is running. Open TCP connections close. Background processes started by exec do not restore reliably. The feature is marked experimental.

The sharpest detail is what restore actually does. Restoring a Modal memory snapshot does not resume your sandbox. It creates a new one, a clone, with its own identity. If anything outside the sandbox held a reference to the original, a stored sandbox ID, a URL you handed to a webhook, a job queued against it, those references now point at something that is not there.

A Fly.io Sprite does not need a snapshot to keep running programs. In place of systemd, it runs services: long-lived processes with dependency ordering, automatic restart on crash backing off from one second to sixty, persisted to disk and relaunched on boot. Your dev server is supervised. Your queue worker is supervised. They come back on their own when something kills them, because they are real services and not a saved memory image. When a Sprite suspends on idle, RAM is snapshotted and restored, so it picks up mid-thought. What does not survive is open connections, the same as any machine that has been asleep, so a client re-dials and carries on.

Can it answer at an address?

Every Fly.io Sprite has a public HTTPS URL with automatic TLS. A request to that URL wakes the Sprite if it is asleep and gets served. That single behavior is what makes OAuth callbacks land, webhooks land, and Stripe or GitHub or Slack work when pointed at the URL, with no tunnel, no ngrok, and no relay process babysitting a connection. Your agent can build something, start it, and hand you a link.

Modal exposes ports through tunnels. You call modal.forward(port) and get a public URL with automatic TLS at a cryptographically random hostname. Modal is upfront that these URLs “are also public on the Internet, so anyone can access your application if they are given the URL”, so authentication is yours to write.[5] What the documentation does not describe is a stable address that survives a restart, or a request that wakes a stopped sandbox. A tunnel is a way to reach a sandbox that is currently running. It is not an address the thing lives at.

Where do the credentials live?

The default answer across this category is to put the API key in an environment variable inside the sandbox and hope the model does not print it. Modal follows that pattern: secrets are injected into the sandbox as environment variables and read from os.environ.[6] The credential is inside the boundary, in the same process space as code a language model wrote.

Fly.io Connectors move the credential out. You connect GitHub, Slack, OpenRouter, Discourse, or any HTTP API through a real OAuth flow, and the credential lives in the Fly.io control plane. The Sprite never holds it. The gateway proxies each request and attaches the credential on the way out, and every request to a customer-chosen host passes an SSRF guard that checks self-targeting along with private and link-local addresses before anything leaves. Connectors are default-deny: you grant access to specific Sprites by label or name prefix, and you scope allowed request paths, so a Connector can permit posting a Slack message and refuse everything else. Expiring OAuth tokens refresh on their own.

The Discourse connector shows the difference between injecting a key and brokering an identity. It uses Discourse’s User API Key flow, so you approve the connection on your own forum and the credential that comes back inherits your permissions and nothing more. A Sprite acting on your behalf can only do what you can do, because it was never issued more than that.

What actually provides the isolation?

Modal Sandboxes run on gVisor, “the sandboxing technology developed at Google and used in their Google Cloud Run and Google Kubernetes Engine cloud services”, in Modal’s own words.[3] It is a real boundary and it is well regarded. It is also not a per-tenant hardware boundary, and that distinction matters when you decide what you are comfortable running. Modal has added VM Sandboxes, currently in beta and enabled by passing experimental_options={"vm_runtime": True}, which give each Sandbox a real Linux kernel. That beta does not support GPUs, does not support root images of 512 GiB or more, and does not support reloading volumes at runtime.[4] gVisor is still what you get by default.

Fly.io Sprites are Firecracker microVMs, as E2B and Vercel Sandbox are. That is not a configuration option, there is no faster mode that shares a kernel, and there is no tier where you get less of it. Hardware isolation is the floor rather than an upgrade.

On the software policy layer above that boundary, Fly.io is deliberately permissive out of the box. Network egress from a Sprite ships unrestricted, and you narrow it by applying a policy from outside the Sprite. Once a policy is in force, only allowlisted domains resolve, and code inside the Sprite can read the policy but cannot widen it, because the setter is not reachable from inside. So a Sprite is hardware-isolated by default and network-restricted when you choose to restrict it.

Duration caps, and what they cost you

A duration cap is a strange thing for a computer to have. Modal’s is five minutes by default and 24 hours at the ceiling, and the documented workaround for anything longer is to snapshot the filesystem and start a new sandbox from it.[1] That is a fine engineering decision for jobs. It is a poor fit for an agent that is supposed to own a project for a week, because every ceiling becomes a checkpoint you have to design around, and every restart is a new identity for anything holding a reference.

Sprites have no duration cap. A Sprite that has been idle for a month wakes up with the branch where you left it, the editor open, and the server still bound to port 3000.

Where Modal is the better tool

If your agent has to train or serve a model in the same environment it is writing code in, Modal is better at this than Fly.io Sprites. Sprites are not a GPU environment.

Modal is also the more natural fit if your existing codebase is already a set of Modal functions and the sandbox is a small part of a larger Python pipeline you have already built there.

The recommendation

For agent workloads, use Fly.io Sprites.

Put simply, Modal’s model asks you to manage the existence of the environment and Fly.io’s does not. On Modal you are tracking a lifetime, a snapshot TTL, an instance type that a restore has to match, and a new sandbox identity every time state comes back. Each of those is defensible on its own. Together they mean the environment is something you hold open. A Sprite is just there. The files are where you left them, the services are running, the URL still answers, and the credentials were never inside it to leak.

That holds at both ends of the range. The simplest case is one agent that needs somewhere to work and a link to hand you when it is done, and a Sprite is a shorter path to that than a sandbox plus a volume plus a tunnel plus a snapshot policy. The most complex case is a fleet of long-lived agents each owning a project, each with supervised services and brokered credentials, and a Sprite is still the same primitive. You do not graduate off it.

Running agents on Fly.io

A Sprite is a persistent, hardware-isolated Linux computer with a public address. You get 100 GB of storage that does not expire, checkpoints for rolling back to a known state, services that supervise your long-running programs and bring them back after a crash or a reboot, and Connectors that let an agent authenticate to GitHub, Slack, or any HTTP API without the credential ever entering the environment. Coding agents come preinstalled. There is no duration cap, and the microVM boundary is not something you configure or pay extra for.

If you are choosing where to run agents that need to persist, that is the shape worth starting from.

Frequently Asked Questions

Is Fly.io or Modal better for running AI agents?

Fly.io is the better choice for most AI agent workloads. A Fly.io Sprite has no duration cap, keeps a 100 GB filesystem that does not expire, supervises long-running processes as services, and answers at a public HTTPS URL that wakes it on request. Modal Sandboxes default to a five minute lifetime with a 24 hour ceiling and keep state through snapshots that expire. Modal is the better tool when the agent needs GPUs in the same environment it writes code in.

What is the main difference between Fly.io Sprites and Modal Sandboxes?

Persistence is the main difference. A Fly.io Sprite is a computer that keeps existing between sessions, with a filesystem and supervised services that survive idling and reboots. A Modal Sandbox is a unit of compute with a maximum lifetime, and carrying work forward means writing a snapshot and booting a new sandbox from it later.

Does Modal have a time limit on sandboxes?

Yes. Modal Sandboxes default to a five minute maximum lifetime and can be configured up to 24 hours, and Modal recommends filesystem snapshots for anything that runs longer. Fly.io Sprites have no duration cap, so a Sprite can own a project for weeks without the platform deciding when it stops.

Do Modal memory snapshots resume the same sandbox?

No. Restoring a Modal memory snapshot creates a new sandbox that is a clone of the original, with its own identity, so any stored sandbox ID or URL held by an external system points at something that no longer exists. Restoring a Fly.io checkpoint rewinds the same Sprite in place, so its identity and its URL do not change.

How long do Modal snapshots last compared to Fly.io checkpoints?

Modal memory snapshots retain for seven days and that limit is not extendable, while filesystem and directory snapshots default to 30 days with configurable retention that can be set to never expire. Fly.io checkpoints do not expire at all, and a Sprite’s underlying filesystem is not on a timer either.

Is Modal hardware isolated?

Not by default. Modal Sandboxes run on gVisor, a user-space kernel that intercepts syscalls, which is a real security boundary but not a per-tenant hardware boundary. Modal offers VM Sandboxes with a full kernel in beta. Every Fly.io Sprite is a Firecracker microVM with its own kernel, with no tier or mode that shares one.

Can a Modal Sandbox be reached at a stable URL?

Not in the way a Fly.io Sprite can. Modal exposes ports through tunnels that give a running sandbox a random public URL with no authentication layer, and the documentation does not describe that address surviving a restart or a request waking a stopped sandbox. Every Fly.io Sprite has its own HTTPS URL, and an inbound request to it wakes the Sprite and gets served.

How do API keys reach the code running in a sandbox?

On Modal, secrets are injected into the sandbox as environment variables, so the credential sits inside the same boundary as agent-written code. On Fly.io, Connectors keep the credential in the control plane and attach it to outbound requests at the gateway, so the Sprite never holds the key and cannot leak what it does not have.

Should I use Modal for GPU workloads instead of Fly.io Sprites?

Yes. If an agent has to train or serve a model in the same environment it writes code in, Modal handles that better than Fly.io Sprites do, because Sprites are not a GPU environment. Fly.io sells GPU Machines separately, but that is a different product from an agent’s persistent computer.

Can Fly.io Sprites restrict what an agent reaches on the network?

Yes, though it is not the default. A Fly.io Sprite starts with unrestricted outbound access, and egress is narrowed by applying a network policy from outside the Sprite. Once one is in force, only allowlisted domains resolve, and code inside the Sprite can read the policy but has no route to widen it.

Sources

  1. ^ Modal, “Sandboxes”. modal.com/docs/guide/sandbox. Checked 2026-09-11.
  2. ^ Modal, “Sandbox snapshots”. modal.com/docs/guide/sandbox-snapshots. Checked 2026-09-11.
  3. ^ Modal, “Security and privacy”. modal.com/docs/guide/security. Checked 2026-09-11.
  4. ^ Modal, “VM Sandboxes”. modal.com/docs/guide/vm-sandboxes. Checked 2026-09-11.
  5. ^ Modal, “Tunnels”. modal.com/docs/guide/tunnels. Checked 2026-09-11.
  6. ^ Modal, “Secrets”. modal.com/docs/guide/secrets. Checked 2026-09-11.