Choosing a tier
A decision procedure for tier selection, the common mis-selections, and what each one costs.
The rule is one sentence: pick the lowest tier whose capability set covers the action. Everything below is how to apply it without guessing.
Decision procedure
Answer in order. Stop at the first yes.
Does the action need a graphical desktop — a native app, a non-automatable UI, a human-visible screen? -> Tier 4 Does it need a real browser — JS-rendered DOM, a logged-in web session, a site with no API? -> Tier 3 Does it need a shell, arbitrary CLIs, a package manager, or a filesystem that persists across calls? -> Tier 2 Does it need to execute untrusted, model-written code? -> Tier 1 Otherwise it's your own reviewed code, not model-authored code that needs gVisor's extra isolation. -> Tier 0
Decision table by workload
| What the agent is doing | Tier | Why not lower | Why not higher |
|---|---|---|---|
| Look up a record in a CRM | 0 | Your own reviewed code, no untrusted input shaping it | gVisor's extra isolation buys nothing for code you wrote and trust |
| Send an email, create a ticket | 0 | Same: a fixed call your own code makes | — |
| Compute a statistic over a returned dataset | 1 | Model-written code must run somewhere isolated | No persistent filesystem, no packages needed |
| Parse an uploaded CSV and chart it | 1 | Needs execution | Stays in-process with pandas and matplotlib preinstalled |
| Clone a repo, run the test suite | 2 | git and pytest are shell binaries | A browser adds nothing |
| Build a container image | 2 | Needs a daemon and a real kernel surface | — |
| Run a migration against a customer database | 2 | Needs the CLI and a scoped secret | — |
| Scrape a JS-rendered page | 3 | No shell tool renders the DOM | No desktop needed; headless is enough |
| Fill in a multi-step web form behind a login | 3 | Needs a real browser session | — |
| Operate a legacy desktop application | 4 | No web surface exists | Nothing higher |
| QA a desktop app's visual output | 4 | Needs real rendering and input | — |
Common mis-selections
Using tier 3 for something that is an HTTP call
The single most expensive mistake. An agent asked to "get the price from this page" often has a JSON endpoint available. Tier 3 costs roughly 45× tier 0 per second and starts in seconds rather than milliseconds.
Check: does the target have an API, an RSS feed, or server-rendered HTML? If yes, a tier 0 fetch
tool or a tier 1 httpx call does the job.
Using tier 2 as a long-lived box
Sessions are not servers. A tier 2 session held open for an hour because "the agent might come back" bills for 3600 seconds of microVM time. The pattern that replaces it: snapshot on last use, restore on next use. Restore is sub-second and storage is three orders of magnitude cheaper than running compute.
Hold open 1 h: 3600 × tier2.session_s Snapshot + restore: 1 × snapshot write + ~2 GiB-h of storage + 1 restore
Using tier 1 expecting a full toolchain
A single shell command run directly works fine on tier 1. What doesn't is code running inside tier
1 spawning its own subprocess (os.system, subprocess.Popen) — that's blocked at the runtime
boundary, not merely absent from the image, and teams discover it the hard way after assuming
"shell command" and "subprocess from code" are the same capability. If the work actually needs a real
filesystem, installed CLIs, or a process calling out to other processes, it is tier 2 work.
Using tier 4 for browser work
A full desktop running Chrome costs over 3× a headless browser microVM and starts several seconds slower. Tier 4 is for the case where the application is not a browser. If the target is a web page, tier 3 is the answer even when the automation is complex.
Spinning a new session per agent step
Each POST /runs one-shot pays a start. An agent loop of twenty steps against the same workspace
should create one session and issue twenty runs against it, not twenty one-shot runs.
One-shot runs are correct when steps are genuinely independent and state must not leak between them — evaluation harnesses, untrusted multi-tenant code execution, anything where a fresh filesystem per call is a feature.
Cost worked example
An agent that reads a support ticket, queries a database, generates a chart and emails it.
| Approach | Tier | Shape | Approx. relative cost |
|---|---|---|---|
| Naive: one desktop session for everything | 4 | 1 session × 90 s | 13,500 |
| Better: one CLI session for everything | 2 | 1 session × 45 s | 1,125 |
| Right: split by action | 0/1/0 | 2 fast Tier 0 calls + 1 code run of 4 s | ~34 |
The split version is roughly 400× cheaper than the naive one and finishes faster, because three of the four steps run on Tier 0's lightest, fastest container instead of a heavier tier's sandbox.
The generalisable lesson: decompose the agent's plan by capability, not by convenience. One session that can do everything is the expensive default.
Tier and latency budget
If the agent loop has a response-time budget, the tier choice spends most of it.
| Loop budget | Feasible tiers | Notes |
|---|---|---|
| < 100 ms per step | 0 | Only Tier 0's lightest, fastest container fits |
| < 500 ms per step | 0, 1 | Tier 1 warm p95 is 250 ms |
| < 2 s per step | 0, 1, 2 | Tier 2 warm p95 is 600 ms |
| < 10 s per step | 0–3 | Tier 3 warm p95 is 3 s |
| No tight budget | 0–4 | Tier 4 warm p95 is 6 s |
For a tight budget at tier 2 or above, pre-warm: create the session while the model is still thinking, so the start overlaps the inference rather than following it. See session lifecycle.
Policy can lower the effective tier
A tier is the ceiling of a capability set, not a guarantee the session gets all of it. A tier 2
session under a restrictive CLI allowlist has fewer capabilities than its tier implies. Use this to
grant tier 2's filesystem and shell while permitting only git, node and pnpm. See policy
engine.