Architecture One-Pager
Solution Architecture v1.0 · open source on raw/bare-metal compute · Platform Architecture · 2026-10
Cloud Development Environment Platform · Solution Architecture v1.0 · open source on raw/bare-metal compute · Platform Architecture · 2026-10
The workspace is a snapshot in durable storage, late-bound to a disposable host: hibernation is the normal state, every host is interchangeable, and resume — not create — is the number the product is judged on.
Everyone has met this system from the outside. You click a repository, a machine appears with the code checked out and the dependencies installed, you work in it from a browser or your own editor, and a week later you come back and it is exactly as you left it. The product is simple to describe and the engineering underneath it is not, because three requirements pull against each other. It has to start fast — a resume should feel instantaneous and a first start should feel quick — which argues for keeping machines warm. It has to be cheap enough to sell per seat, and a developer's workspace is idle for most of the day it is open, which argues for keeping almost nothing warm. And it has to run code nobody reviewed, written by a developer or increasingly by an agent, on a machine whose user has root, which argues for a boundary no container shares a kernel across. A fourth pressure has arrived more recently and changes the shape of the problem: two of every three workspaces are now started by a coding agent, headless, in bursts an order of magnitude above steady state, living seven minutes rather than ninety.
Stop treating the workspace as a machine. A workspace is a persisted artefact — a chain of content-addressed blocks in regional object storage, rooted at a prebuild, with a memory image while it is recently used — and a host is something it is temporarily incarnated on. A request arrives at a regional edge that authorises it and holds the connection open; an admission layer ahead of placement enforces quotas and sheds agent creations before human resumes; placement picks any eligible host; the host agent restores a Firecracker microVM from the snapshot, fetching blocks on first touch so the wait does not scale with disk size, and reconciles the clock, the network topology and the brokered credentials before the session attaches. While the workspace runs, the filesystem flushes asynchronously every five minutes and all egress passes a per-workspace policy point on the host. When nobody is working, a composite liveness signal hibernates it, and the host keeps nothing. The control plane records all of this and sits outside the data path, so a management-plane outage stops new workspaces rather than stopping work.
What it is, and what it is not
- A persisted artefact occasionally incarnated on a host — not A long-lived virtual machine with backups
- A platform whose hardest problem is resume — not A platform whose hardest problem is provisioning
- A fleet where every host is disposable — not A fleet where workspaces have homes
- A system that assumes root inside the workspace is compromised — not A system that trusts the tenant's own code
- Two workload classes sharing one substrate — not A developer product that also has an API
- A business built on idleness — not A business built on utilisation
- A platform that refuses explicitly under load — not A platform that queues invisibly
- A credential broker with minutes-long, workspace-scoped tokens — not A machine with the developer's own token in it
- A region-pinned service that becomes unavailable — not A global service that fails over
The decisions that are the architecture
- The workspace is a snapshot, late-bound to a disposable host (ADR-01) — Identity and everything needed to run live in durable storage no host owns. This is the one decision every later view either honours or contradicts: it makes hibernation normal, host loss a latency event, patching a scheduling problem, and the economics possible.
- Filesystem truth is object storage with a local overlay and lazy block fetch (ADR-02) — An immutable, content-addressed chain plus a disposable host-local copy-on-write view, so time-to-usable is independent of disk size and no host holds anything authoritative.
- Memory state is kept while a workspace is recent, and decays after a week (ADR-03) — Sub-second resume where it is actually used; storage bounded by recency rather than by population, with a correct — not merely degraded — cold-boot path afterwards.
- One microVM per workspace, boundary per workspace not per tenant (ADR-04) — Untrusted code is the normal case, so the boundary sits below the kernel the adversary controls, and one developer's fork bomb is never their colleague's problem.
- Credentials are brokered, scoped and never resident (ADR-05) — Anything written into the workspace is assumed exported, so the defence is scope, a fifteen-minute lifetime, host-attested identity and a recorded issuance — not secrecy.
- Egress posture is deny-by-default for agents, allowlisted for humans (ADR-06) — The strictest boundary goes where the code is least reviewed and the tolerance for refusal is highest, with a registry proxy making the strict default survivable.
- A prebuild is a post-create snapshot with an explicit validity predicate (ADR-07) — Create becomes restore, and staleness becomes decidable from digest, definition revision and lockfile hash rather than guessed from age.
- Capacity pressure is an explicit, class-aware refusal (ADR-08) — Agent creations shed before human resumes, and every rejection names its cause and is retryable. A queue an orchestrator cannot see is worse than a no it can.
- An authorised connection is the resume request (ADR-09) — The edge holds the client with a progress stream naming the phase, so the wait has a cause, and gateways stay stateless with respect to workspace identity.
- Idleness is a composite signal on the host, with a bounded veto (ADR-10) — Unforgeable where it costs money, informative where it protects the developer, and measured in both error directions because one destroys trust and the other destroys margin.
- Own bare metal and oversubscribe memory 4:1 (ADR-11) — The snapshot strategy needs hardware virtualisation and local NVMe, the price needs the density, and the promise is honest only because hibernation can take the memory back.
- The control plane holds records, never content (ADR-12) — Running workspaces survive its outage, the backup problem collapses onto two stores, and the most attractive target in the system holds no source code.
- Drain is the only maintenance mechanism (ADR-13) — Patching, hardware failure, rebalancing and idleness all use hibernate-and-resume-elsewhere, so the platform's most critical path is exercised continuously rather than during incidents.
- Residency outranks availability (ADR-14) — Content never leaves its region; cross-region resume is a tenant-authorised migration. The promise that is kept is the one whose breach cannot be undone.
Why this should still be right in ten years
The hypervisor, the object store, the orchestrator, the editor and the agents will all be replaced inside this platform's life. These are the properties that should outlast them.
- Identity belongs to the artefact, not the machine holding it. Container images, immutable infrastructure and object-storage-backed databases all made the same move, and all of them outlived the technology that first expressed it. A workspace that is addressable independently of any host survives the replacement of the hypervisor, the disk format and the fleet, because nothing operational is attached to a particular machine. If any single idea in this package is worth keeping, it is this one.
- Put the trust boundary below the operating system the adversary controls. This has held through mainframe partitions, hypervisors, jails and microVMs, and the arrival of code written by models rather than by people has only strengthened it. The specific isolation technology will change — it may become something lighter than a virtual machine and heavier than a container — but the rule that a platform running unreviewed code does not rely on that code's own kernel should not be revisited.
- Cache the expensive step, and make validity a predicate over inputs. Every build system learns this, usually after shipping an age-based cache. Prebuilds, block chains and memory images are all caches here, and each is trusted only because its correctness is decidable from its inputs. Whatever replaces lockfiles and image digests, a cache whose validity is a function of time will still be the kind that is quietly wrong.
- Oversubscription is only honest when you own the mechanism to take it back. Thin provisioning, airline seats and this platform's 4:1 memory ratio are the same bet on a distribution, settled by a mechanism. Build the mechanism first, measure the distribution continuously, and publish the headroom. A design that promises more than it has without a fast, correct way to reclaim it is simply wrong at a time it has not met yet.
- Make the exceptional path the routine one. Drain-and-resume is used for patching precisely because it is also the answer to host loss, idleness and rebalancing. A recovery mechanism exercised only during incidents fails during incidents. This is why the platform has no separate disaster procedure, and it is a property worth protecting against every future feature that would introduce one.
- Rank the promises explicitly. Residency over availability is a product judgement, not a technical one, and it is visible in the topology rather than buried in an incident review. Regulatory commitments about where data lives have hardened over the last decade while availability expectations stayed negotiable; whatever the specific rules become, the habit of ranking promises where the architecture can show the ranking will keep paying.
Non-functional targets
Every figure below is a stated assumption. They are listed with the mechanism that is supposed to deliver them and the view where that mechanism is drawn, so a reviewer can disagree with a number and follow it straight to the decision that depends on it.
| Quality | Target | How it is met | View |
|---|---|---|---|
| Resume with memory state | p50 ≤ 900 ms, p95 ≤ 2.5 s, p99 ≤ 6 s, in-region | Memory image restore plus lazy block fetch, resume triggered by the connection itself with progress streamed | 13 |
| Create from a prebuild | p50 ≤ 8 s, p95 ≤ 25 s; from a warm pool p95 ≤ 3 s | Post-create snapshot restored and rebased onto the newer commit; warm pools claimed rather than created | 14 |
| Create with no prebuild | p95 ≤ 4 min, progress streamed from the first second | Inline build, reported as the cause of the latency rather than hidden | 14 |
| Interactive terminal round-trip | p95 ≤ 45 ms in-region, p99 ≤ 120 ms | Regional edge close to the developer, session proxy on the same path, output queued rather than input dropped | 09 |
| Workspace runtime availability | ≥ 99.95% of workspace-hours monthly | Per-workspace microVM containment, late binding, and drain rather than terminate for all maintenance | 15 |
| Resume success rate | ≥ 99.9% of attempts; a failure leaves the workspace resumable | Integrity verified on restore, retryable failure paths, fencing before any second incarnation | 13 |
| Control-plane availability | ≥ 99.9% monthly, with running workspaces unaffected | Records-only control plane, policy read from a cached projection in the data plane | 08 |
| Creation throughput | 40,000 starts/hour peak, 10× agent burst for 60 s | Warm pools per popular pair plus class-aware admission that refuses explicitly rather than queueing | 02 |
| Snapshot RPO | 5 minutes while running; RPO 0 for control-plane records | Asynchronous flush of the copy-on-write overlay every 5 minutes, synchronous on hibernation | 10 |
| Host-loss RTO | 60 s to resume on another host | Late binding onto any eligible host from the last snapshot, with the lost interval reported to the user | 15 |
| Snapshot volume and durability | 180 TB/day new data, median delta ≤ 2 GB, ≥ 11 nines | Content-addressed blocks deduplicated against the prebuild, ephemeral paths excluded by default | 11 |
| Cost per workspace-hour | ≤ $0.085 active, ≤ $0.004 hibernated, ≥ 60% fleet utilisation | Owned bare metal at 4:1 memory oversubscription with hibernation as the relief valve | 19 |
| Residency | 100% of content and snapshots inside the declared region | Region as a tenant attribute enforced on placement, snapshot write and route; no cross-region replication configured | 16 |
Scope
In scope
- Workspace lifecycle as a state machine — create, run, hibernate, resume, archive, delete — with a durable event stream for billing, audit and tenant automation
- Declarative environment definitions pinned by image digest, prebuilds with an explicit validity predicate, and warm pools per popular (prebuild, machine class) pair
- Per-workspace microVM isolation with enforced resource caps, contained resource exhaustion, and nested containerisation inside the guest
- Durable filesystem persistence as a content-addressed chain with lazy block fetch, plus memory snapshots inside a decay window
- Connectivity for browser editors, desktop tunnels, SSH and headless agent clients under one authorisation model, with resume-on-connect and private-by-default preview URLs
- Agent sessions as a declared workload class: programmatic creation, burst absorption, per-principal ceilings, stricter egress and idle defaults, and a session record that outlives the workspace
- Brokered, workspace-scoped, short-lived credentials over a host side channel, and a per-workspace egress policy point with a pull-through registry proxy
- Idle hibernation on a composite liveness signal, cost attribution per workspace-hour, and reclamation to a cold tier
- Fleet operations: drain-and-evacuate for patching, the platform's own delivery pipeline with a snapshot-fidelity gate, and the observability that makes start latency attributable by cause
Explicitly out of scope
- CI/CD pipelines and production deployment, which belong to the ci-cd-platform package — this platform runs developer code and does not ship it
- The internal service catalogue and golden-path scaffolding, which belong to the internal-developer-platform package
- The editor itself and the agent's reasoning loop: the platform supplies the machine and the boundary, not the tooling inside
- Source control, identity and the package ecosystems, all of which are dependencies rather than components
- Collaborative multi-session editing with presence and conflict handling, named in phase 3 and deliberately not designed here
- Live migration of running microVMs, explicitly rejected in ADR-13 rather than deferred
- Cross-region replication of workspace content, which ADR-14 refuses by default and offers only as an authorised migration
What a four-week prototype should prove
The prototype's job is to falsify the three claims the whole design rests on — that a snapshot-first workspace can resume fast enough to feel instantaneous, that lazy block fetch keeps that true for a large disk, and that idleness can be detected well enough to oversubscribe memory — on a handful of hosts and a few dozen developers, not to build a platform.
- Three bare-metal hosts, one region, one environment definition, 40 volunteer developers and a scripted agent workload at the assumed 65/35 mix, with resume latency measured client-side from click to usable shell as the headline number from day one
- A snapshot path end to end: content-addressed blocks in an object store, a host-local copy-on-write overlay, lazy block fetch, and memory snapshot and restore for one machine class
- A composite idleness signal shadowed against a client-heartbeat baseline for fourteen days, with both error directions counted rather than a single threshold tuned
- Admission ahead of placement with per-principal ceilings and class-aware refusal, so the burst behaviour can be measured rather than argued about
- Drain as the only maintenance mechanism, exercised weekly on real workspaces rather than rehearsed at night
- A hibernated 8 GB workspace with a memory image resumes to a usable shell at p95 ≤ 2.5 s with a warm block cache, and a 32 GB workspace with a completely cold cache resumes within the same budget — if time-to-usable tracks disk size, lazy block fetch has not delivered what ADR-02 claims
- A full build is started immediately after a resume, the worst case for lazy fetch: the build completes without stalling on block fetches, and the fetch-induced slowdown is bounded and reported rather than discovered
- A host carrying 40 live workspaces is drained under real use: every workspace resumes elsewhere, the pause each developer sees is single-digit seconds, resume success is 100% across the drain, and the evacuation's snapshot and fetch traffic is within the storage tier's headroom
- A host is killed with workspaces mid-edit: no workspace is ever incarnated twice, every affected workspace resumes from its last snapshot within 60 s, and the lost-interval report matches the work actually lost rather than reassuring the developer
- Fourteen days of shadowed idleness detection produce zero false hibernations during builds longer than ten minutes, and catch abandoned workspaces within the configured window — the number that decides whether 4:1 memory oversubscription is defensible at all
- A 10× agent creation burst is applied for 60 s: refusals rise immediately, each names its cause and is retryable, and resume latency for human workspaces does not move — which is the entire argument for refusing over queueing
Open risks, carried rather than hidden
| Risk | If it lands | Response |
|---|---|---|
| Resume latency does not hold outside the prototype's conditions — larger disks, colder caches, noisier hosts | The product's central promise fails in exactly the situation that matters most, a developer returning to real work, and the whole snapshot-first design loses its justification | Treat resume as a budgeted, attributed number with a per-phase breakdown from day one; keep the cold-boot path correct rather than merely present so a missed memory snapshot degrades instead of failing; size the NVMe cache from the measured working set rather than from the disk size |
| The idleness signal is wrong in either direction | False hibernations during long builds destroy trust in a way that is remembered for months; missed idleness quietly erases the margin that justifies owning the fleet | Measure both error directions as product metrics, keep the veto bounded and logged, and treat the oversubscription ratio as a parameter tuned against measured hibernation accuracy rather than as a constant |
| The host agent — the most privileged component, adjacent to hostile code — is compromised through the vsock channel | A single escape reaches brokered credentials and other tenants' workspaces on the same host, which is the failure the whole isolation argument exists to prevent | Keep the vsock protocol minimal, versioned and fuzzed; treat the guest agent as advisory with no authority; patch on the drain mechanism so the kernel and agent cadence never competes with availability |
| Agent demand grows faster than owned capacity can be added | Chronic refusals push agent orchestrators to other platforms and make the ceiling look like unreliability rather than policy | Keep rented bare metal as a pre-integrated overflow path rather than a future project, forecast per (prebuild, machine class) from the event stream, and publish headroom so capacity decisions precede the refusals |
| Strict egress and brokered credentials are experienced as friction and are switched off tenant by tenant | The platform's security argument erodes to a default nobody runs, while remaining the easiest exfiltration path in the tenant's estate | Invest in the paved path — a fast, complete registry mirror and credential helpers that make expiry invisible — and report posture adoption as a platform metric, not as a tenant choice to be won once |
| A region-wide failure strands a region's developers with no technical answer | A day of lost work for an entire population, and pressure during the incident to replicate content out of the region in breach of the residency promise | State the asymmetry in the contract before it is tested, rehearse the authorised migration path so it is minutes rather than a project, and keep per-region headroom so a partial failure does not cascade |
The reasoning behind every component and technology choice is in the Architecture Decision Record: 14 records across 5 areas, each with the alternatives that lost and what the choice costs.