Running AI Agents on Cloudflare Without Always-On VMsBeta accessEarly Beta Access<br>All our Agents get computers, we pay for almost none<br>Ankush · Author<br>Writes about Construct, AI agents, and developer tools.<br>Published July 31, 2026 · @ankushKun_
engineering<br>cloudflare<br>durable-objects<br>infrastructure
Construct is an AI employee. You hand it a job. It goes and does the job, without you having to babysit it.
To do that with agents like Hermes or OpenClaw, you spin up a VPS. Real CPU. Real disk. A full Linux machine that stays on between turns. That costs real money, and the moment more people sign up to poke around and never come back, it murders your infrastructure bill .
We give every Agent that same kind of computer.
Don't get excited - we are not paying for all of them.
The computers work. When someone asks Construct to do something, the machine wakes up and does it. When the tab goes quiet, nothing stays on just to cosplay as useful. Idle boxes are a kink we refuse to subsidize.
We like edging. So we put the whole stack on the edge. Agent loop in a Durable Object. Linux summoned for one tool call, then gone. Disk that is not a disk. The bill only finishes when somebody actually works.
This post is how we built that. Behaviour, constants, and tradeoffs are production.
Meet Construct→
The bill that scaled with people who never came back
The default way to run an AI agent is to hand it a Linux box and walk away.
Not stupid. Agents are trained on bash. Bash wants a filesystem and a process table. The lazy move is a machine that stays up between turns. Lazy is usually correct.
Until the invoice arrives.
We know that invoice because we signed it first. Construct's original backend was a Bun and Elysia monolith on a VPS. SQLite on local disk. nginx out front. Roughly 1,300 lines of container management whose only job was handing every user their own box. It worked. Growing the product meant growing a fleet of real machines with real disks, billed through the silent hours where nobody typed a character.
That is the expensive version of "every user gets a computer." Technically true. Financially a treadmill. Someone who signed up once and ghosted cost the same as a power user. The product could not scale if the bill scaled with accounts instead of work.
We killed it on 30 March 2026. Commit title: "migrate backend from VPS monolith to Cloudflare Workers." Everything in this post starts there.
Hono on Workers. Per-user WebSocket hub in a Durable Object with hibernation. Container object that archived to R2 on sleep and restored on wake. D1 for relational state. R2 for files. Frontend on Workers assets. Two days later we dragged the leftover container infrastructure into a legacy folder and wrote the plan we still run: the agent runs headlessly inside Durable Objects.
Containers and Sandboxes went GA on 13 April 2026. We moved onto the Sandbox SDK once it had the shape we wanted.
We did not see the future. We stared at a cost curve that scaled with signups instead of usage, bet on Durable Objects before there was a tidy product name for the thing, and watched the platform walk to the same answer. camelAI hit the same wall and reached nearly the same conclusion independently. Validation, or a warning about people who write posts like this. Both.
Only half a computer deserves to be awake
"The agent needs a computer" is two unrelated things taped together.
Agent loop: transcript, tool routing, model calls, memory recall. This is how Construct thinks across a turn.
Machine: the thing that runs pdftotext, converts a spreadsheet, compiles a project, unzips the archive somebody should not have uploaded. This is how Construct touches a real filesystem.
Only the second needs Linux.
The first needs durable state and a socket. Cloudflare sells exactly that. Split the two and the expensive half stops needing to be alive at all.
Everybody argues about which model to use. Almost nobody argues about which half of their stack is getting paid to nap. That is the whole post, in one sentence.
Get beta access→
Linux shows up, edges the job, and leaves
This is the section the title is about.
Each Construct agent gets one Durable Object, resolved by name. Sessions are rows inside it, not objects of their own. Temporary subagents run as delegated sessions on the same parent. Fan out a job - buy concurrency, not instances. That is how Construct can split a big ask without spinning up a fleet.
The transcript lives in that object's SQLite. Two things, kept apart on purpose. One table is the append-only message log the user scrolls through. A separate record holds the compaction summary plus a watermark of how far it has already consumed. That second one is what reaches the model. Conflate them and you pay, per turn, to re-send an afternoon of conversation to a model that did not ask for it. People do this. At scale.
Hibernation is where the bill actually moves. We use the WebSocket hibernation API, stash...