Waiting & Latency UX

9 min read

H13
Playbook · Agent UX & Human Interaction

Waiting: the first ninety seconds decide everything.

Shaving eight seconds off a forty-second agent run buys you almost nothing, because the wait a user cannot estimate is the one they abandon — and abandonment tracks legibility, not duration. The lever is the denominator: publish the plan before the work starts, report against it in units the user can check, and the same forty seconds stops being a void and becomes a queue with a visible end. Everything else on this page is a consequence of that one move.

STEP 1

Agent runs are off the interactive-latency scale, and speed will not rescue them.

The classic response-time thresholds — roughly a tenth of a second for "instant", about a second to preserve flow, ten seconds as the limit of held attention — were derived for operations whose duration a user can guess before starting. An agent that plans, calls six tools, reads three files and writes a report lives one to two orders of magnitude beyond that scale, and no amount of optimisation moves it back onto it.

  • The relevant variable is estimability, not seconds. People wait patiently for a progress bar at 60% and impatiently for a spinner at four seconds, and the difference is that one of them supports a prediction. A wait a user can price is a cost they accept; a wait they cannot price is a risk, and the response to unpriced risk is to leave.
  • Optimising the model is the expensive lever with the worst return here. Halving generation latency on a run whose wall clock is dominated by tool calls, retries and a rate limit changes the number the user feels by a few percent. Publishing a plan costs one extra sentence in a prompt and changes it categorically.
  • The wait is not uniform, and users notice the texture. A run that streams for six seconds, stops dead for twenty during a tool call, then resumes reads as broken, not as slow. Silence during a tool call is the single most common unforced error in agent interfaces, and it is a rendering bug rather than a performance one.
  • Do not fake it. Simulated progress bars, invented percentages and typing indicators that do not correspond to work are a one-time loan against trust, repaid with interest the first time the bar sits at 94% for a minute. See designing for trust.
STEP 2

Four clocks, and the one that actually predicts abandonment.

"Latency" collapses four different measurements that behave differently and are fixed by different work. Instrument them separately or you will optimise the wrong one.

  • Time to first token. The one every dashboard shows. It matters only as a liveness signal — proof the request was received. Past a second or so of improvement it buys nothing, and it is routinely bought at the expense of the next clock.
  • Time to first checkable evidence. The first moment the user sees something they can independently verify: a file path, a search result, a row count, a URL. This is the clock that governs whether they stay. Prose about what the agent intends to do is not evidence; the first tool result is. Most agent interfaces hold this back for thirty seconds while narrating.
  • Time to reviewable artifact. When there is enough output to start reading — a draft, a diff, a partial table. Getting a rough artifact in front of someone early and refining it beats a perfect artifact later, because reading time and generation time then overlap instead of queueing.
  • Time to done. The only one users are asked about in surveys and the least useful for design. It is also the one that varies most between runs, which is why a point estimate ("about 30 seconds") is worse than a shape ("usually under a minute; long ones take five").

The practical consequence of ranking these: reorder the plan so that something checkable happens first, even when that is not the most logical order of work. An agent that searches before it reasons has a worse plan and a much better wait, and on most tasks the difference in outcome is smaller than the difference in abandonment.

STEP 3

Give the wait a denominator.

A user cannot estimate a wait without knowing how many things are left. Agents can supply that number, because they plan — and most interfaces throw the plan away and render only its execution.

  • Show the plan before the first step runs. Four to six named steps, in the user's vocabulary, not the tool's: "find the invoices", "check them against the ledger", "write the summary". This converts an unbounded wait into three of four, which is a number a person can hold.
  • Then the plan is a promise, and revisions must be visible. This is the cost of the technique and the reason to keep the plan short. If the agent discovers two more steps, say so — "found 14 mismatches, adding a reconciliation pass" — because a silently growing plan is worse than no plan, and a step that disappears reads as a skipped check.
  • Prefer counted units over percentages. "6 of 23 files" is honest, self-correcting and immune to the 94% problem. A percentage on an agent run is a guess presented with two significant figures.
  • Name the step in domain terms, and log the tool call underneath. "Reading the Q3 ledger" for the surface; fs.read(/data/q3.csv) in the expandable detail. The two audiences are different and both are real — the layering rules are in progressive disclosure.
  • Never let the surface go silent for more than a few seconds. A long tool call needs its own visible state ("waiting on the search API, 12s"), and a retry after a rate limit needs to be said out loud rather than hidden — a stall the user can name is tolerable, a stall they cannot is a failure.
STEP 4

Streaming is motion, not progress.

Token streaming was the right answer for chat, where the stream is the deliverable, and it gets imported into agent interfaces where it usually is not. Motion reassures for about ten seconds and then stops working, and on a long run it actively misleads.

  • Streaming reasoning tokens does not tell the user how far along the run is. Three paragraphs of deliberation and one line of it look identical as a completion signal. Worse, a fluent stream implies competence the trace does not warrant — the reasoning text is generated output, not a log of what determined the answer, which is the point of chain-of-thought faithfulness.
  • Users read what streams past, and hold you to it. Anything visible during the run is treated as a commitment. An agent that streams "I'll also update the changelog" and then does not has, from the user's side, failed at a task nobody assigned. Stream conclusions and actions; keep speculation out of the visible channel.
  • Stream the artifact, not the monologue, when there is an artifact. A diff appearing hunk by hunk, a table filling in row by row, a document assembling section by section — each of those is motion and progress, and it starts the review clock early.
  • Interruptibility is what makes visible work honest. If a user can see the agent heading somewhere wrong and cannot stop it, showing them was a cruelty. Every visible step needs a stop that takes effect within a step boundary; see interruption, steering and handoff.
STEP 5

Know when to stop designing the wait and hand off.

Somewhere between one and three minutes, depending on how much the user cares about the task, the correct design stops being a better progress display and becomes a release. Holding attention on a page for eight minutes is a worse outcome than sending someone away and fetching them back.

  • Decide the handoff threshold explicitly, and make it a product decision. Below it, the user watches and can steer. Above it, the run detaches and notifies. The failure mode is having no threshold, which produces an interface that begs for attention for ten minutes and then delivers.
  • Offer the handoff, do not impose it. "This looks like a five-minute job — want me to ping you?" respects a user who genuinely intends to supervise, and converts the rest. Offer it at the moment the estimate changes, not at the start when nobody has committed anything yet.
  • The handoff must survive the user leaving. A detached run that stalls on an approval nobody is present to give is a deadlock, not a safety control. Decide before dispatch which decisions the run may take alone and which are worth blocking for — this is the whole subject of async and away UX, and it starts the moment you cross the threshold.
  • Design the return, because it is the expensive part. Someone who comes back after nine minutes needs to reconstruct what happened, and a raw scroll of tool calls makes them pay for it in full. What they need is the outcome first, the decisions second, and the log third.

A useful test for any agent surface: if the user closed the tab right now, what would they lose? If the answer is "the whole run", you have built a system that requires attention it has not earned. If the answer is "nothing — it keeps going and tells them", the wait has stopped being a design problem at all.

STEP 6

Failing inside the wait, and the numbers to watch.

Long runs make failures expensive in a specific way: the user has already spent the time when they find out. Two rules follow, and then the instrumentation.

  • Fail early and loudly rather than late and completely. A run that detects at second four that a credential is missing must say so at second four. The worst pattern in agent UX is a four-minute run that ends in "I was unable to access the database", because the wait was spent and nothing was returned — see designing for failure and recovery.
  • Return partial work, always. Six of twenty files processed, with the six named, is a result. Discarding partial output on failure throws away the only thing the wait bought.
  • Abandonment rate by elapsed time. The headline number, and the one that tells you where your handoff threshold actually is rather than where you set it. Bucket it by ten-second intervals and the cliff is usually obvious.
  • Time to first checkable evidence, at p50 and p90. Optimise this before time-to-done. The p90 is where the abandonments live, and it is almost always a slow tool rather than a slow model.
  • Silence gaps: the longest interval with no surface update, per run. Nobody instruments this and it correlates with abandonment better than total duration does. Alert when p95 exceeds a handful of seconds.
  • Estimate error. If you show an estimate, measure how wrong it was, and prefer a range you hit to a point you miss. Systematic optimism is the fastest way to make every future estimate ignored.

Do these three before touching latency itself: emit the plan as a short numbered list before step one, reorder the plan so the first step produces something the user can independently check, and give every tool call over two seconds a visible named state. They cost a prompt change and a component, they apply to every run rather than to the tail, and together they move perceived speed further than any model or infrastructure change available to you.

Related: async & away UX for what happens after the handoff, streaming & partial output for the mechanism, the latency budget for the voice case where none of this slack exists, and cost, quality & latency for the trade-off underneath.