What It Takes to Own Your Agent Platform: The Firecracker Fleet Series in One Read
Over seven parts, we built a self-service platform for running eve.dev agents on a fleet of Firecracker microVMs in AWS — from an empty account to a system where a developer runs one command and gets a live, isolated agent at a URL. This post is the map. Read it first if you want the shape of the thing before the details, or last if you just finished the series and want to see how the pieces lock together. Either way, it is the whole platform in one place.
The premise is worth restating, because it is the reason to do any of this. Vercel's eve gives you a great hosted story: vercel deploy and your agent's code execution is isolated by Vercel Sandbox. For most teams that is the right answer. But some teams need to own the isolation layer — for control over the VM boundary, for the cost profile of raw EC2, for data residency, or because agents running arbitrary tool code demand a boundary you can inspect and shape yourself. This series is what owning it actually looks like.
The Whole Platform in One Picture
Here is everything the series builds, and the path one deploy takes through it:
developer ┌──────────────────────────┐
$ fleet-deploy ./my-agent ── build rootfs ──► │ S3 image bucket (P3) │
│ │ versioned agent images │
│ POST /agents (IAM-signed) └────────────┬─────────────┘
▼ │ host pulls image
┌─────────────────────┐ place (bin-pack) ┌─────────────▼────────────┐
│ control plane (P4) │ ────────────────────►│ host fleet ASG (P2) │
│ API GW + Lambda │ │ bare-metal *.metal │
│ DynamoDB registry │◄─── heartbeat ───────│ ┌──────┐ ┌──────┐ │
│ EventBridge │ + capacity │ │ µVM │ ··· │ µVM │ │
└─────────────────────┘ │ └──────┘ └──────┘ │
▲ └────────────┬─────────────┘
│ placement lookup │ tap + NAT (P5)
┌────┴───────────────┐ my-agent.fleet.dev ┌─────────────▼────────────┐
│ ALB + front proxy │◄───── clients ─────────│ routing layer (P5) │
│ (P5) │ └──────────────────────────┘
└─────────────────────┘ all inside one VPC (P1) · operated by the loops in P7
Six systems, one network. Every arrow was a part.
The Series, Part by Part
If the diagram is the what, this is the reading order — each part deploys on its own and builds on the network beneath it.
- Architecture & the Network Foundation — the VPC, public/private subnets, and the three security groups (ALB, hosts, control plane) that encode who may talk to whom. The room everything else lives in.
- The Host Fleet — an Auto Scaling Group of bare-metal hosts, a launch template that installs Firecracker and a host-agent daemon, the least-privilege IAM role, and the capacity model that decides how many agents fit on a box.
- Packaging an Agent as a microVM Image — a
build-rootfs.shthat bakes an eve agent into a bootable ext4 image, a versioned S3 bucket, per-microVM secrets via MMDS, and snapshots for warm sub-second boots. - The Control Plane — API Gateway and Lambda over a DynamoDB registry, a race-safe bin-packing scheduler, and EventBridge decoupling the API from the work. The part where a deploy request becomes a running agent.
- Networking & Routing — tap devices and NAT per microVM, an ALB with a wildcard certificate, per-agent subdomains, and a host-local front proxy that finds an agent wherever it was placed.
- The Deploy Workflow — IAM auth on the API, a
fleet-deployCLI, GitHub Actions shipping on merge via OIDC, and a live preview agent for every pull request. - Fleet Operations — event-driven autoscaling with drain hooks, a reconciliation loop that reschedules agents off a dead host, fleet-wide observability, and the cost-per-agent model.
All of it lives on the series hub, and all of it is AWS CDK in TypeScript — reviewable, versioned, deployable, and destroyable.
The Threads That Hold It Together
The parts are a build order; these are the ideas that recur across all of them. If you take nothing else from the series, take these — they are what make the design coherent rather than a pile of services.
One constraint shapes everything: bare metal. Firecracker needs /dev/kvm, which only bare-metal EC2 instances expose. That single fact makes hosts large and coarse-grained, makes packing agents onto them the thing that determines the bill, and makes the whole platform a bin-packing problem. Every capacity and cost decision traces back to it.
Split desired state from actual state. The agents table says what should be running; the placements table says what is. Keeping them separate is what makes recovery trivial: every failure — a crash, a scale-in, a botched boot — becomes the same reconciliation loop noticing the two disagree and re-driving events until they match. You do not write recovery code per failure mode; you write one loop.
Make the control plane event-driven and serverless. The API records intent and emits an event; a scheduler acts on it later. That decoupling buys a fast API, automatic retries, an audit trail, and clean hooks for the operations loops — and it means there is no long-running scheduler process to babysit, just Lambdas that fire when there is a decision to make.
Let the database enforce correctness. Placement never oversubscribes a host because capacity reservation is a single DynamoDB conditional write — the check and the decrement are atomic. No locks, no scheduler singleton. That one ConditionExpression is what lets placement be a stateless function that runs many copies at once.
Security groups are the design, not a detail. "The ALB can reach agents, the control plane can reach hosts, nothing else can reach anything" is written as role-to-role security-group rules, not IP ranges — so the rules stay correct as hosts come and go. The network topology is the security model.
Immutable images, movable pointers. Every build is a content-addressed version; current is just a pointer. Deploys and rollbacks are the same cheap operation in opposite directions, and the whole history is auditable.
Packing density is the unit economics. Because bare metal is essentially the entire bill, cost per agent is cost per host divided by how densely you pack it. A fleet running half-full costs twice as much per agent as one that consolidates — which is why bin-packing, tightest-fit placement, and drain-and-consolidate all point the same direction.
Should You Build This?
Be honest about the answer. The series built a learning platform — enough to understand how every layer fits, deliberately short of production hardening (the jailer, per-tenant egress policy, a real secrets backend, warm snapshot pools). Standing up something like it for real workloads is a genuine project, and for many teams it is the wrong one.
Build the fleet when you need to own it: when the VM boundary, the cost model, or data residency has to be yours, and when you have enough agent volume that packing them onto shared bare metal actually beats per-agent hosting. For one agent, or for multi-tenant isolation you would rather not operate, the series' own opening advice stands — vercel deploy and Vercel Sandbox give you the same microVM boundary with none of this machinery. Owning it is a real cost; the point of the series is that now you know exactly what that cost is.
Where to Start
If this overview sold you on the idea, do not start with Part 1 of the fleet series — start one level down. Boot a single microVM by hand with the single-VM guide: one host, one Firecracker microVM, one agent, provisioned with CDK. Everything the fleet does is that, multiplied — and it is far easier to see the moving parts once before a fleet replicates them. From there, the series hub takes you through all seven parts in order.
And if you would rather have a platform like this built and handed off — reproducible, cost-aware, and documented so your team can own it — that is the kind of work we do. The whole series is, in a sense, a worked example of it.