← all articles

Cost engineering for computer-use agents: screenshots and steps

the first computer-use agent I ran for more than a demo looked cheap on paper. a task took about forty steps, each step cost a screenshot, and I multiplied the per-image price by forty and wrote a number on a sticky note. the invoice was several times that number. the sticky note was wrong because I had priced the screenshots as if each one was sent once. they are not. every step resends the whole conversation so far, and the conversation is mostly screenshots.

that one fact is the whole article. cost in a computer-use loop is not linear in steps, it is closer to quadratic, and the lever that matters most is not the model price but how many images are in the context at each step and whether they hit a cache. if you run these agents for a handful of tasks a day, you can ignore all of this. if you run them as a fleet, against your own properties or on behalf of consenting users, the difference between a naive loop and a tuned one is the difference between a product and a hobby.

I am an operator based in Singapore, and everything here comes from running browser and desktop agents in production, plus the vendor docs I cite. I will not give you benchmarks I did not run. where I show numbers, they are arithmetic from a stated formula or an assumed price, labeled as such, so you can swap in your own. prices change often, so check the vendor pricing page on the day you read this. anything I date is “as of October 2026”.

background and prior art

a computer-use agent is a loop. the model gets a screenshot, emits an action (click at x,y, type text, press a key, scroll), your harness executes it, takes a new screenshot, and sends it back. Anthropic documents this as the computer use tool, and OpenAI documents a similar loop in its computer use guide. the shape is the same across vendors: observation in, action out, repeat until done or until you stop it.

the cost levers were already known from ordinary chat workloads. images are billed as input tokens, and Anthropic’s vision docs give an approximate formula: tokens ≈ (width in px Ã, height in px) / 750, with images whose long edge exceeds roughly 1568 px resized down first. prompt caching, described in the prompt caching docs, lets you reuse a long prefix at a fraction of the normal input price, with cache reads priced at a small multiple of base input and cache writes at a premium. what is new in the computer-use setting is that the thing growing in your context is not text but images, which are large, opaque, and often useless after two or three steps.

earlier browser-agent work mostly avoided the problem by not using screenshots at all. DOM and accessibility-tree agents send text, which is cheaper and more precise, but they break on canvas apps, remote desktops, native apps, and pages whose DOM is hostile. screenshots are the fallback that always works, and the price of “always works” is what we are engineering down.

the core mechanism

why cost is quadratic

let s be the token cost of one screenshot, and n the number of steps. at step k the request contains k screenshots (assuming you keep them all), plus the system prompt, the tool definitions, and the text of every action and reply so far. the total input tokens billed across a run is roughly:

total_image_input = s * (1 + 2 + ... + n) = s * n * (n + 1) / 2

double the steps and you roughly quadruple the image input. this is why a run that takes eighty steps because it got confused costs far more than two runs of forty. it is also why the cheapest step is the one you never take.

the four levers

there are four things you control, and they multiply.

  • s, the tokens per screenshot: set by the resolution you capture and send.
  • n, the step count: set by task design, action batching, and how often the agent wanders.
  • images retained per request: set by whether you prune old screenshots.
  • the price per token actually paid: set by caching, model choice, and batch eligibility.

most teams find the first lever and stop. the biggest wins in my runs came from n and caching.

lever one: screenshot size

using the vision formula, here is what common capture sizes cost per image, before any extra resizing the API applies:

  • 1024x768 (XGA): about 1,049 tokens
  • 1280x800 (WXGA): about 1,365 tokens
  • 1568x882 (a 16:9 shot at the long-edge limit): about 1,844 tokens

the computer use docs recommend staying around XGA or WXGA, and there is a reason beyond cost. the model’s click coordinates are in the space of the image it saw. if you send a 1920x1080 capture that the API downsizes, you must scale coordinates back up yourself, and sloppy scaling is a classic source of misclicks and therefore retries. capture at the size you send, and set the virtual display to that size. do not capture big and hope.

the tradeoff is legibility. at XGA, small body text on a dense dashboard can become unreadable, and the agent will respond by zooming, scrolling, or guessing, all of which add steps. I treat resolution as a per-task setting, not a global one. a form-filling flow on a clean page runs fine at 1024x768. a dense admin table gets 1280x800 or a cropped region.

lever two: step count

every step is one model call and one screenshot. ways I cut n:

  • start the agent in the right place. if the task begins on a logged-in page, do the navigation and login in plain Playwright and hand the agent a page that is already at the interesting part. I wrote about the session side of this in attaching to an existing Chrome session vs launching a fresh browser. a lot of “agent steps” in naive runs are just cookie banners and sign-in.
  • prefer keyboard actions. one ctrl+l, type URL, enter sequence beats several clicks. tab-and-type through a form beats clicking each field.
  • let the harness batch. if your tool wrapper lets the model emit several actions between screenshots, take the screenshot only at the end of the batch. only do this for actions whose outcome is predictable. batching a click that opens a modal and then a click inside the modal is how you click the wrong thing.
  • skip screenshots on no-ops. after a pure wait or a failed action that changed nothing, you may not need a fresh image.
  • give the model a text escape hatch. a tool that returns the page’s visible text or a specific element’s text costs a few hundred tokens against over a thousand for an image, and it answers “what does this say” without squinting at pixels.

lever three: pruning old screenshots

the model rarely needs the screenshot from twelve steps ago. it needs the current screen, maybe the previous one, and a text trace of what it did. so you drop old images and replace them with a short text placeholder. the reference implementation Anthropic publishes for computer use includes an option along these lines, keeping only the N most recent images, though you should read the current quickstart rather than trust my memory of its flag names.

pruning turns the quadratic into something near linear. with a window of w images, the image input per step is capped at about w times s, so the total is roughly s * w * n once n exceeds w. but pruning has a cost that is easy to miss, and I cover it in the failure modes: it changes the prefix, and a changed prefix kills your cache.

lever four: caching

cache reads are billed at a fraction of base input, and writes at a premium over base. both multipliers are in the prompt caching docs. as of October 2026, the docs list reads at 0.1x base input, 5-minute writes at 1.25x, and 1-hour writes at 2x, but confirm these on the day you read this because the numbers are the most likely thing to move.

in a computer-use loop, step k’s request is step k-1’s request plus one new action and one new screenshot. that is a near-perfect cache shape: a growing, append-only prefix. so you mark the end of the latest content with a cache breakpoint on each request, the previous step’s prefix is read from cache at the discounted rate, and only the new screenshot is written.

two details bite people. first, the 5-minute default lifetime refreshes on each cache hit, so an active loop keeps itself warm, but any pause longer than five minutes (a human approval, a slow page, a queue delay) means the next step rewrites the whole prefix at the premium. second, the docs describe a limited lookback window, on the order of twenty content blocks, for finding a cache hit behind a breakpoint. a computer-use step adds several blocks (assistant text, tool use, tool result with image), so long runs can outrun the lookback if you only ever place a breakpoint at the very end. check the current docs and move breakpoints forward deliberately on long runs.

worked examples

the following examples use the vision formula for image size, and an assumed input price of $3 per million tokens. that price is an assumption for illustration, not a quote from any current price list. replace it with the real number from the Anthropic pricing page for the model you run. I count only screenshot tokens, and ignore the system prompt, tool definitions, action text, output tokens, and any thinking tokens. real invoices are higher. the point is the ratios.

example 1: a 40-step run, no tricks versus caching

task: a 40-step flow on a WXGA display (1280x800, about 1,365 tokens per screenshot), all screenshots retained.

  • naive image input: 1,365 Ã, (40 Ã, 41 / 2) = 1,365 Ã, 820 = 1,119,300 tokens
  • at the assumed $3 per million: about $3.36 per run

now add caching. each step writes one new screenshot (1,365 tokens at 1.25x) and reads everything before it at 0.1x.

  • writes: 40 Ã, 1,365 = 54,600 tokens, at 1.25x is 68,250 billed-equivalent tokens
  • reads: 1,119,300 minus 54,600 = 1,064,700 tokens, at 0.1x is 106,470 billed-equivalent tokens
  • total: 174,720 billed-equivalent tokens, about $0.52 at the assumed price

that is roughly an 85% drop in the image-input line from caching alone, assuming the loop never pauses past the cache lifetime and the prefix never changes. both assumptions fail in the real world, which is the next example.

example 2: the same run, resolution as the variable

same 40 steps, all screenshots retained, no caching, so the effect of resolution is isolated.

  • XGA: 1,049 Ã, 820 ≈ 860,000 tokens
  • WXGA: 1,365 Ã, 820 ≈ 1,119,000 tokens
  • 1568x882: 1,844 Ã, 820 ≈ 1,512,000 tokens

going from XGA to the large 16:9 capture costs about 76% more image input for the same number of steps. whether that is worth paying depends on whether the extra legibility removes steps. on a clean page it will not. on a dense table it may, if it stops the agent from scrolling around and re-reading. I measure this on my own tasks by comparing step counts at two resolutions on the same task set before choosing, and I would suggest you do the same rather than copy my default.

example 3: cutting n with a scripted front half

take the same task and script the first 25 steps (open the site, authenticate with a stored session, navigate to the right record, open the right tab) in Playwright, which costs zero model tokens. the agent handles only the last 15 ambiguous steps.

  • image input at 15 steps: 1,365 Ã, (15 Ã, 16 / 2) = 1,365 Ã, 120 = 163,800 tokens
  • versus 1,119,300 for the all-agent run, so about 85% less, before caching

this is the single biggest lever in my runs, and it is not clever. quadratic cost means shorter agent runs are disproportionately cheaper. the hybrid also fails more predictably: the scripted half either works or throws a clean error, and the agent’s judgment is spent only where judgment is needed. for fleets, the orchestration side matters here, and I covered it in the best ways to orchestrate many Playwright browser sessions for a fleet of agents.

edge cases and failure modes

pruning that destroys the cache

if you drop the oldest screenshot at every step once you pass your window, the start of the message list changes every step. caching matches on an exact prefix, so every step becomes a full rewrite at the write premium. you pay more than if you had done nothing.

counter-strategy: prune in chunks, not one at a time. let the history grow to, say, 12 images, then collapse the oldest 8 into text in one step and re-cache. you pay one rewrite per chunk instead of one per step. the right chunk size depends on your cache economics, so work it out with the multipliers above. a simple rule of thumb: pruning pays off only when you save more in read tokens than you lose in rewrite premium, and for short runs (under 15 steps or so, in my experience) it usually does not, so do not bother.

cache expiry during human or queue pauses

anything that pauses a run for over five minutes lets the cache expire. approval gates, rate-limit backoff, a worker getting preempted, a slow CAPTCHA-free but heavy page. the next step silently re-bills the whole history at the write premium.

counter-strategy: log cache read and write token counts per step (the API response usage fields report them) and alert when writes spike mid-run. if pauses are expected, evaluate the 1-hour cache option, whose write multiplier is higher, against the cost of re-writing. if a run might pause for hours, checkpoint the state and restart with a compact text summary rather than carrying images across the gap. for the checkpointing side in graph-based runners, see self-hosted LangGraph checkpointing vs LangGraph Cloud for long tool calls.

the stuck loop

the model clicks a button, nothing visibly changes, it clicks again, forever. each iteration costs a screenshot, a model call, and a growing context. this is the one failure that can turn a $0.50 run into a $20 run without any code error.

counter-strategy: hard budgets, enforced in the harness, not the prompt. cap steps per task, cap total tokens per task, and cap consecutive identical actions. I also hash each screenshot (a perceptual hash is fine) and abort when the last three frames are identical after different actions. a budget breach should end the run with a clear status and the last screenshot saved for review, not retry automatically. automatic retries of a stuck run double the bill for the same failure.

coordinate drift and silent scaling

if your display size, the captured image size, and the size the API sees do not agree, clicks land in the wrong place. the agent sees the miss, tries again, and your step count inflates. this one looks like a model quality problem and is actually a harness bug.

counter-strategy: fix the virtual display resolution, capture at exactly that size, and run a calibration check at the start of a deployment: draw a marker at a known coordinate and confirm the agent’s click on it lands within a few pixels. rerun it whenever you change the browser, the OS, display scaling, or the headless mode. library upgrades can also shift behaviour in ways that look like agent errors, as in why upgrading Playwright can silently break CORS-dependent requests your agent relies on.

paying for a model that is too smart or too weak

a bigger model may finish in fewer steps but costs more per token. a smaller one may wander. neither is a safe default. the only honest comparison is cost per successful task, which includes failed runs, retries, and the human time to review failures. I keep a table per task type: success rate, median steps, p90 steps, and total spend divided by successes. the p90 matters more than the median, because the tail is where the budget goes. I compared model behaviour on browser tasks in which LLMs actually hold up running a browser-use agent in production right now, and the ranking there changes faster than any article can keep up with, so rerun the comparison on your own tasks every time a new model ships.

screenshots as a data exposure

this is a cost of a different kind. every screenshot you send is a copy of whatever was on screen, including names, emails, and tokens in a URL bar. if you retain screenshots for debugging, you are storing that data. only run agents against accounts and properties you own or users who have consented, keep screenshot retention short, and mask or crop regions the agent does not need. cropping also cuts tokens, so privacy and cost point the same way here.

what we learned in production

the biggest shift in how I work was to stop thinking about “cost per step” and start thinking about “cost per completed task, including the failures.” per-step cost is a vanity number. the stuck loops, the cache expiries and the mis-scaled clicks are all invisible in it. once I logged per-run token usage with cache read and write splits, plus a step count and an exit reason, the money was obviously in three places: runs that hit the step cap, runs that paused across cache expiry, and tasks where I had left the agent to do navigation I could have scripted. fixing those did more than any resolution tuning.

my practical order of operations, for a new task type: script everything deterministic first, then pick the lowest resolution that does not raise the step count, then add cache breakpoints, then set step and token budgets with a clean abort, and only then consider chunked pruning. I put the tracing in before any of it, because you cannot tune what you cannot see. if you have not picked tooling for that yet, the best tools for tracing and debugging AI agents is where I would start. for the full index of what we have written on running agents, see the blog index.

one note on mobile. if your agent drives an Android app rather than a desktop browser, screenshots are tall phone frames and the same math applies, with the added wrinkle that a real device behaves differently from an emulator. for that case I run tests on cloudf.one, which rents real Android phones in Singapore on dedicated hardware, each with a persistent Singapore mobile IP, controlled from the browser. it is Singapore-only, so it only helps if Singapore is where your app behaviour needs to be tested. the cost engineering above is the same either way.

I will repeat the caveat I started with: I did not benchmark vendors against each other for this article, and the numbers above are arithmetic on stated assumptions. your tasks will have different step counts and different cache hit patterns. measure on your own workload before you commit to a budget.

references and further reading

Written by Xavier Fok

disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-10-15.

free download
Why did my agent get blocked? A triage checklist

The checks we run, in order, when a browser or phone agent starts failing: network, fingerprint, behaviour, account. Leave your email and we will also tell you when we publish a new field note, a few times a month at most.

from the team behind this site
A Singapore mobile IP for browser agents

Singapore Mobile Proxy runs real mobile IPs on SingTel, StarHub and M1, with sticky sessions so one task keeps one IP. Singapore only: a fit for SEA or location-agnostic work, the wrong tool if you need a US IP.

see plans →
from the team behind this site
A real Android phone for phone-use agents

cloudf.one hosts real Android phones in Singapore on dedicated hardware, each with a persistent Singapore mobile IP. For agents that need an actual device and a stable carrier identity.

get a phone →
read on
More from The Agent Ops Report

Blocks, sessions, retries, traces, cost per task and phone-use agents. Browse all articles →