all posts

PandaStack vs Morph Cloud: Snapshot-First Sandboxes

Ajay Kumar··9 min read

Most sandbox comparisons are a fight about cold-start numbers. This one isn't, because PandaStack and Morph Cloud already agree on the thing most of the market gets wrong: for AI agents, the interesting primitive is not "start a machine" — it's "save this exact machine, then branch it." Morph is a cloud sandbox platform whose headline capability is instant snapshotting and branching of running VM state for agent workloads. That makes it the closest philosophical neighbour PandaStack has. If you're choosing between us, you've already made the important architectural decision; what's left is a set of engineering questions about how each implementation behaves under your specific workload.

Disclosure up front: I'm Ajay, the founder of PandaStack. This is a vendor's comparison and you should read it as one. The rule I've set myself and will hold to for the whole post is that I cite specific measured numbers only for PandaStack, and describe Morph only qualitatively, from its widely-stated positioning as cloud VM sandboxes for AI agents with fast snapshot and branch-from-state. I'm not going to invent Morph's latencies, pricing, quotas, API names, or feature checkboxes — a comparison built on numbers I guessed at is worse than no comparison. So this post is shaped as "here is how to evaluate," not "here is their spec sheet," and every claim about Morph should be verified against Morph's own current documentation.

Founder bias, stated plainly: I built one of these two things. Where I give hard numbers, they're PandaStack's own published measurements. Where I discuss Morph, I stay qualitative on purpose and tell you to check their docs — their product moves, and my paraphrase would go stale faster than their changelog. The checklist in the middle is the part I'd actually want you to use, and it's designed so that running it honestly could send you to them.

Why snapshot-and-branch is the right primitive for agents

A traditional sandbox API assumes a linear life: create, run, destroy. That model comes from CI, where the job is a straight line and a failure is just a red build. Agents don't work like that. An agent explores: it takes an action, discovers the action was wrong, and needs to get back to where it was — except "where it was" includes an installed dependency tree, a warmed interpreter, a half-migrated database, and a file it edited two steps ago. Reconstructing that from a script is possible; reconstructing it reliably, on every rollback, is not.

Three concrete moves fall out of getting this right, and they're the moves both platforms are built around.

Checkpoint before a risky tool call

Your agent is about to run a migration, a package upgrade, a `rm` it composed itself, or a shell command an LLM wrote at 2am with great confidence. Snapshot first. If it goes badly, you restore rather than apologise. This turns an entire class of "the agent destroyed its own environment" incidents into a retry, and it's cheap enough to do reflexively when the snapshot primitive is fast.

Branch N candidate fixes in parallel

The strongest pattern in agentic coding right now is best-of-N: get to a decision point, then explore several continuations from the identical starting state and keep whichever one passes the tests. Doing that with fresh sandboxes means paying setup cost N times and — worse — accepting that the N environments aren't actually identical. Branching from one live state means they are identical by construction, which is the only way the comparison between candidates is meaningful.

Resume a session hours later

Long-running agents have gaps: waiting on a human review, a nightly job, a rate limit. Keeping a VM hot through a six-hour gap is a way of paying for nothing. Snapshotting the session and restoring it later — with the process tree and memory intact, not just the files — turns idle time into storage cost instead of compute cost. Same capability as checkpointing, pointed at economics rather than correctness.

Both PandaStack and Morph position themselves around these moves, which is genuinely unusual. Most sandbox products bolt snapshotting on later as a persistence feature, and it shows in the latencies. So the question between us isn't "who has snapshots" — it's how each implementation behaves when you lean on it hard.

The evaluation checklist to run against both

This is the part I'd keep if you only kept one section. Run these questions against Morph's docs, against PandaStack's docs, and — for anything that matters — against a real spike. A vendor claim you didn't reproduce is a rumour with a logo on it.

  1. Branch latency, same-host versus cross-host. Nearly every fast branching figure in this category is a same-host figure, and fairly so — sharing pages with a parent on one machine is where the trick lives. Ask what happens when that host is full: cross-host branching moves a memory image over the network first, and it is meaningfully slower everywhere. Get both numbers.
  2. Does the snapshot capture memory state, or only disk? The most consequential question, and the one most often answered vaguely. Disk-only restores your files; full-machine restores your running processes and your warmed interpreter. Two very different products wearing the same word. Test it: start a process, snapshot, restore, and see whether it's still there.
  3. How long do snapshots persist, and what do they cost at rest? Enthusiastic branching produces a lot of saved state. Find out the retention policy, whether snapshots expire, whether there's a count limit, and how storage bills separately from compute. This is the line item that surprises people in month three, not week one.
  4. Network egress control. Agent code reaches the internet. Know what you can restrict — allowlists, blocklists, egress off entirely — and at what layer it's enforced. An unrestricted sandbox running untrusted code is a proxy for your credentials and your IP reputation.
  5. Persistent versus ephemeral lifecycles. Can an environment outlive a request, and what reaps it? Check the idle timeout, whether it's configurable, whether "idle" means no API calls or no CPU, and what happens to state at that boundary. Silent reaping of a long agent session is a bad way to learn this.
  6. Self-host and open-source availability. Some teams can't send customer code to a third party — regulated data, VPC requirements, or a security team that reasonably wants to audit the execution layer. It's a binary, and it's often the whole decision. Verify Morph's current position with them, not from a competitor's post.
  7. Region coverage and data residency. Where do sandboxes physically run, and can you pin them? Orchestrator-to-sandbox latency matters in a tight agent loop, and residency rules may make certain regions mandatory.
  8. SDK ergonomics. You'll know within an hour of writing real code: how branching is expressed, how errors surface, whether streaming exec exists, whether the types help. Subjective — trust your own hands over anyone's screenshot.
  9. Observability. When an agent run goes wrong at 3am, what can you see? Per-sandbox logs, exec-level timing, lifecycle events, scrapeable metrics. Snapshot-heavy architectures are harder to debug precisely because state travels.
Question two on that list — memory state versus disk-only — deserves the same scepticism aimed at me. If a snapshot or branch feature matters to your architecture, don't accept the word "snapshot" from any vendor, including PandaStack, without running the test: start a long-lived process, snapshot, restore elsewhere, and check what survived. Fifteen minutes of testing beats fifteen pages of marketing.

Where PandaStack is concrete

Here's my side of the checklist with actual numbers attached, so you have something falsifiable to benchmark against.

Every create is a snapshot restore. There is no warm pool of idle VMs waiting to be handed out — a create restores a baked Firecracker snapshot on demand, which lands at 179ms p50 and roughly 203ms p99, of which the restore step itself is about 49ms. The remainder is network-slot allocation, rootfs reflink, and a readiness probe. The one slow path is the very first spawn of a brand-new template, which does a genuine cold boot in around 3 seconds and bakes the snapshot that every subsequent create reuses. The architectural consequence matters more than the number: because we don't hold idle capacity, there's no warm pool for you to size, pay for, or watch go stale.

Branching is copy-on-write at both layers. A fork clones a running sandbox: guest memory is shared with the parent and copied only on write, and the rootfs is cloned by filesystem reflink so blocks are shared until something modifies them. Same-host forks land in 400–750ms. Cross-host forks are 1.2–3.5s, because the memory image has to come from object storage before the restore can happen — that's the honest cross-host tax I told you to ask every vendor about, including me.

The supporting machinery is where the latency comes from, and it's the part you'd otherwise build yourself. Each host pre-allocates 16,384 /30 subnets with their network namespaces, veth pairs, and TAP devices already standing, so attaching a sandbox to the network is a patch rather than a construction project. Guest memory can also be streamed on demand from object storage over userfaultfd: a host serves page faults by fetching only the pages the guest actually touches, backed by a shared on-disk chunk cache, instead of downloading a multi-gigabyte memory image first.

PandaStack is also broader than a sandbox product, which is either a feature or irrelevant surface area depending on what you're building. Managed PostgreSQL 16 runs as a dedicated microVM per database on a durable volume (create takes 30–90s, because it blocks until Postgres genuinely accepts connections rather than lying to you early), and git-driven app hosting builds a repo and serves it behind a stable URL with blue-green deploys. Both sit on the same isolation substrate as the sandboxes, so what your agent builds has somewhere to live. The core is Apache-2.0 and self-hostable on your own KVM hosts — that's our answer to checklist item six; go get Morph's answer from Morph.

Side by side, honestly

Every Morph cell below is either qualitative or an explicit instruction to check their docs. That asymmetry is the point — it's not a rhetorical trick, it's me refusing to fill in cells I can't source.

  • Core primitive — PandaStack: snapshot-restore on every create, plus copy-on-write fork of a running sandbox. Morph: snapshot and branch-from-running-state is their headline capability; the shared philosophy is real.
  • Create latency — PandaStack: 179ms p50, ~203ms p99 via snapshot restore; ~3s for the first-ever spawn of a new template. Morph: fast startup is central to their positioning; check their docs and benchmark it yourself.
  • Branch latency — PandaStack: 400–750ms same-host, 1.2–3.5s cross-host. Morph: check their docs, and ask specifically whether a published figure is same-host, cross-host, or both.
  • What a snapshot captures — PandaStack: full machine state, memory plus rootfs, via Firecracker. Morph: branching from running state is their stated model; verify the exact semantics in their docs and with a live-process test.
  • Isolation boundary — PandaStack: Firecracker microVM, own guest kernel per sandbox. Morph: cloud VM sandboxes; confirm the specific hypervisor and boundary in their documentation.
  • Self-host — PandaStack: yes, Apache-2.0 core on your own /dev/kvm hosts. Morph: check their docs for current deployment and licensing options; don't assume either way from this post.
  • Snapshot cost at rest — PandaStack: object storage under your own lifecycle policy; self-hosted means your bucket, your bill. Morph: check their pricing and retention policy directly.
  • Platform breadth — PandaStack: sandboxes plus managed PostgreSQL 16, app hosting, and functions on one substrate. Morph: focused on the sandbox and snapshot surface; check their docs for current scope.
  • Region coverage — PandaStack: hosted regions plus wherever you run your own hosts. Morph: check their docs; availability changes and matters for residency.
  • SDKs — PandaStack: Python (pandastack), TypeScript (@pandastack/sdk), and a CLI. Morph: SDKs are available; try both on a real task, since ergonomics are subjective.

Code: checkpoint, then branch N candidates

This is the best-of-N pattern in its simplest honest form — get an environment into a known state, checkpoint it, fan out candidate fixes from that identical state, and keep the one whose tests pass.

from pandastack import Sandbox

# One environment, warmed once: repo cloned, deps installed.
base = Sandbox.create(
    template="code-interpreter",
    ttl_seconds=900,
    metadata={"run": "issue-1234", "stage": "base"},
)
base.exec("git clone --depth 1 https://github.com/acme/service /work")
base.exec("cd /work && pip install -r requirements.txt", timeout_seconds=300)

# Checkpoint before anything risky touches this state.
checkpoint = base.snapshot()
print("checkpointed:", checkpoint)

# Fan out N candidate fixes from the *identical* live state.
# Same-host forks land in 400-750ms, so N=4 is cheap enough to be routine.
candidates = [
    "patches/retry-backoff.diff",
    "patches/null-guard.diff",
    "patches/reorder-init.diff",
    "patches/widen-timeout.diff",
]

winners = []
for patch in candidates:
    branch = base.fork()
    branch.filesystem.write("/work/candidate.diff", open(patch).read())
    branch.exec("cd /work && git apply candidate.diff")
    result = branch.exec("cd /work && pytest -q", timeout_seconds=600)

    if result.exit_code == 0:
        winners.append((patch, result.duration_ms))
        print(f"PASS {patch} in {result.duration_ms}ms")
    else:
        print(f"FAIL {patch}: {result.stderr[-400:]}")
        branch.kill()  # a wrong branch costs nothing to discard

base.kill()
print("passing candidates:", winners)

The thing to notice is what isn't in that loop: no repeated clone, no repeated `pip install`, and no anxiety about whether the four candidates ran against subtly different environments. They didn't — they ran against the same one, four times, which is what makes the comparison between them worth anything.

Code: hibernate and resume a long session

The second pattern is the six-hour gap. A persistent sandbox holds the session; hibernate parks it when the agent is waiting on a human; the next request wakes it with its state intact.

from pandastack import Sandbox

# Persistent: this one is exempt from the idle reaper and holds session state.
session = Sandbox.create(
    template="agent",
    persistent=True,
    metadata={"session": "review-4417", "owner": "agent-worker-2"},
)

session.exec("cd /work && ./bootstrap.sh", timeout_seconds=600)
session.filesystem.write("/work/NOTES.md", "waiting on human review of PR #4417\n")

# Agent is blocked on a human. Park it instead of paying for an idle VM:
# hibernate snapshots the machine and stops burning compute.
session.hibernate()

# ... hours later, the review lands. The next operation wakes it, with the
# session's state restored rather than rebuilt from a setup script.
print(session.filesystem.read("/work/NOTES.md"))

status = session.exec("cd /work && git status --short", timeout_seconds=60)
print(status.stdout, status.exit_code)

session.kill()

The Python SDK also supports use as a context manager if you'd rather not hand-roll teardown, and the TypeScript SDK mirrors the same surface via `import { Sandbox } from "@pandastack/sdk";`. Templates available out of the box are base, code-interpreter, agent, browser, and postgres-16.

Choose Morph if / choose PandaStack if

I'd genuinely rather you pick correctly than pick me, partly out of principle and mostly because a customer who chose wrong churns in four months and tells people why.

Choose Morph if

  • You want a fully managed, hosted service and no interest in operating KVM hosts, an agent fleet, or snapshot storage. Legitimate position, and the main thing we can't give you without ops work.
  • Their branching, measured on your workload, beats ours. Run the same best-of-N loop on both. If their numbers win for your shape of environment, that's your answer, and no prose from me should override it.
  • Their SDK fits how your agent is already written. Ergonomics compound; an API that maps onto your control loop saves more engineering time than a marginal latency difference.
  • You want a focused tool. If you don't need managed Postgres or app hosting, PandaStack's breadth is surface area you'll never touch.
  • Their regions, retention policy, or pricing fit your constraints better once you've checked their docs — which, one final time, is the source of truth about them, not this page.

Choose PandaStack if

  • You need to self-host — data residency, a VPC requirement, or a security team that wants to audit the execution layer rather than trust it. The core is Apache-2.0 and runs on your own KVM hosts; that's a binary difference no feature comparison outweighs.
  • The no-warm-pool model suits your economics: every create is a 179ms p50 snapshot restore with no idle capacity held in reserve, so there's no warm pool to size and nothing to pay for between bursts.
  • You want copy-on-write branching with published, falsifiable numbers on both sides of the host boundary: 400–750ms same-host, 1.2–3.5s cross-host. Hold me to those.
  • You need more than sandboxes on one isolation substrate — managed PostgreSQL 16 and git-driven app hosting, so what the agent builds has somewhere to run.
  • You want to read the code that runs your untrusted workloads, which is increasingly a procurement requirement rather than a preference.

Run the benchmark, not the comparison table

Here's the spike I'd run, and it takes an afternoon. Pick one real environment — your repo, your dependencies, not a hello-world. On each platform: create it and time it, cold and warm. Get it to a known state, checkpoint, branch four times, time each branch, and confirm the four really are identical. Start a long-lived process, snapshot, restore, and check what survived. Hibernate for an hour and measure the wake. Try to make an outbound connection you shouldn't be allowed to make. Then look at the bill, including what the saved state costs to keep.

That afternoon will tell you more than this post, Morph's docs, and every comparison table on the internet combined — and it's the only version of this evaluation where neither vendor gets to grade their own homework. If it sends you to Morph, they'll have earned it on the same test I asked you to run on me.

Weighing the wider field? The full guide to E2B alternatives at /blog/e2b-alternatives compares E2B, Modal, Daytona, Northflank, Vercel Sandbox, Fly.io Sprites, and PandaStack across isolation model, hosted-versus-self-host, cold-start, forking, and platform breadth.

Frequently asked questions

What is the main difference between PandaStack and Morph Cloud?

Both treat snapshotting and branching of running VM state as the core primitive for AI agents rather than as an afterthought, which makes them closer to each other than to most sandbox products. The clearest structural difference is ownership: PandaStack's core is open-source under Apache-2.0 and designed to run on your own KVM hosts, so the isolation boundary can live inside your VPC. PandaStack also spans managed PostgreSQL and git-driven app hosting on the same substrate. For Morph's current deployment model, feature set, and pricing, check their own documentation — I deliberately don't characterise those here.

How fast is branching in PandaStack, and how should I compare it to Morph?

A PandaStack fork of a running sandbox completes in 400–750ms on the same host and 1.2–3.5s cross-host, the difference being that a cross-host branch has to pull the memory image from object storage before restoring. When comparing against any other vendor, insist on knowing which of those two cases a published number refers to, because same-host and cross-host branching are different operations with different physics. The right test is your own: warm one environment, branch it four times, and time each branch on both platforms with your real dependency tree rather than a trivial image.

Does a snapshot capture memory state or only the disk?

For PandaStack, a snapshot captures full machine state — guest memory plus the rootfs — using Firecracker's native snapshot support, and a fork shares that memory copy-on-write with the parent. This is the distinction that decides whether a restored environment still has your warmed interpreter and running processes or just your files. It is also the question most likely to be answered ambiguously in any vendor's marketing, so verify it empirically on every platform you evaluate, including this one: start a long-lived process, snapshot, restore, and check what survived.

Can I self-host PandaStack, and can I self-host Morph?

PandaStack's core is Apache-2.0 licensed and built to be self-hosted: you run the control-plane API and a per-host agent on machines with /dev/kvm, and sandboxes execute entirely on your infrastructure. That's the right choice when data residency, compliance, or auditability rules out sending customer code to a third party, and the wrong choice if you don't want to operate KVM hosts. For Morph's current position on self-hosting or source availability, check their documentation directly rather than inferring it from a competitor's blog post.

What should I budget for snapshot storage when branching heavily?

This is the cost line that surprises teams in month three rather than week one, because enthusiastic branching produces a lot of saved state. Ask every vendor three things: how long snapshots persist by default, whether there is a count or size limit, and how storage is billed at rest separately from compute. On self-hosted PandaStack, snapshots live in your own object storage under your own lifecycle policy, so it's your bucket and your bill. For Morph's retention and pricing specifics, consult their pricing page — I'm not going to estimate numbers I can't source.

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.