Perceived performance for AI means designing what users see and feel during a wait, not just shortening the wait itself. Real latency is an engineering problem — fewer tokens, faster retrieval, smaller models. Felt latency is a design problem, solved with occupied attention, visible progress, and honest uncertainty signals that keep users in their seats through slow generation.
Quick Answer: You can't always make AI faster, but you can make the wait feel shorter by giving users something to watch — streamed tokens, a stated plan, an echoed query — instead of a blank screen. Occupied time feels short; uncertain, empty time feels long, even when the clock says otherwise.
Why Perceived Performance Matters More for AI Than for Traditional Software
Perceived performance matters more for AI products because generation latency is often irreducible, variable, and invisible in a way traditional page loads never were. A database query is milliseconds; a model reasoning through a multi-step task can take 10-90 seconds with no fixed ceiling, and users have no mental model for why.
Traditional software waits are short and predictable: a spinner for 300ms, a progress bar for a file upload. Users have decades of calibrated expectations for those. AI waits break that calibration. A chatbot might answer in two seconds or take twenty depending on reasoning depth, tool calls, or retrieval — and the user has no way to tell in advance which one they're getting.
This unpredictability is exactly what the psychology of waiting studies. Researchers going back to David Maister's classic service-operations work on queuing psychology identified that occupied time feels shorter than unoccupied time, and uncertain waits feel longer than known, finite ones. AI interfaces routinely violate both principles by default — a static spinner is unoccupied and uncertain at once, which is close to the worst possible combination.
The Psychology Underneath the Wait
The core mechanism is attention allocation. When users have nothing to process, their attention turns inward, toward the wait itself, which makes it feel longer and more effortful. When they're processing something — even something small — the wait becomes background noise instead of foreground anxiety.
Maister's principles, still cited in service-design and UX research today, translate directly to AI interfaces:
- Occupied time feels shorter than unoccupied time. A visible query being parsed feels faster than a blank spinner, even at identical duration.
- Anxiety makes waits feel longer. Not knowing whether the system has stalled or is still working amplifies frustration disproportionately.
- Uncertain waits feel longer than known, finite waits. A progress bar with an estimate beats an open-ended spinner, even when the estimate is imperfect.
- Unexplained waits feel longer than explained waits. "Searching your knowledge base" beats silence.
- Waits before the process starts feel longer than waits during it. This is why echoing the query back instantly matters disproportionately — it moves the "start" earlier in the user's mental clock.
Separating Real Latency From Felt Latency
Real latency is the actual wall-clock time between a request and a usable response; felt latency is the subjective duration a user experiences, which can diverge from real latency by 2x or more in either direction depending on design. Treating these as the same problem is the most common mistake AI teams make.
Engineering teams optimize real latency: smaller context windows, streaming inference, caching, model routing to cheaper/faster variants for simple queries. All of that matters and none of it is a substitute for perceived-performance design, because users abandon based on felt time, not measured time. A 2019 Nielsen Norman Group synthesis of decades of HCI response-time research still cites roughly 1 second as the threshold where users notice a delay, and roughly 10 seconds as the point where attention drifts entirely away from the task — thresholds set well before generative AI existed, and still routinely blown past by a single LLM call.
| Dimension | Real latency (engineering) | Perceived latency (design) |
|---|---|---|
| What it measures | Wall-clock time to response | Subjective felt duration |
| Primary levers | Model size, caching, retrieval speed, infra | Streaming, progress narration, occupied attention |
| Failure mode if ignored | Slow product, high infra cost | High abandonment even on a fast backend |
| Who owns it | Infra/ML engineering | Product design, UX writing |
| Fixable this sprint? | Often no (model constraints) | Almost always yes |
The practical takeaway: if your latency budget is fixed for the next two quarters, perceived-performance work is the highest-leverage thing you can ship this week. It doesn't require touching the model.
Four Techniques That Shape the Wait
Four core techniques — streaming, progress narration, optimistic UI, and skeleton screens — cover most of the perceived-performance surface for AI products. Each has a distinct psychological mechanism and a distinct failure mode when misapplied.
Streaming: Turning Dead Air Into Motion
Streaming works because it converts one long uncertain wait into a series of small, continuously-updating certainties. Instead of "nothing, then everything," the user sees text accumulate token by token, which reads as visible progress even if total completion time is unchanged or slightly longer.
Streaming is now close to table stakes for chat-style AI interfaces — ChatGPT, Claude.ai, and most competitors default to it. The mechanism is Maister's "occupied time" principle in its purest form: reading partial output is the occupation.
When streaming backfires:
- Structured or code output. Watching JSON or a function signature assemble character-by-character can feel worse than a brief wait followed by a clean, complete, syntax-highlighted block — partial structure reads as broken structure.
- Answers that get revised mid-stream. If the model "changes its mind" visibly (a number appears, then gets corrected), streaming exposes the model's uncertainty in a way that erodes trust rather than building it — a case where microcopy for hallucinated answers becomes directly relevant, since the correction itself needs framing.
- Very short responses. Streaming a two-word answer adds visible latency to something that should have felt instant.
Progress Narration: Naming the Work in Flight
Progress narration tells the user what the system is doing right now, converting an unexplained wait into an explained one — directly targeting Maister's principle that unexplained waits feel longer. "Searching 214 documents," "Drafting outline," "Checking sources" all do this.
The key design constraint: narration must be truthful to the actual pipeline, not decorative theater. A label that says "Verifying facts" when no verification step exists is a fabricated-confidence problem, closely related to what confidence displays without scaring users has to navigate — the narration is itself a claim about system behavior, and claims need to be true.
Effective progress narration typically follows a plan-then-narrate structure:
| Stage | What the user sees | Psychological function |
|---|---|---|
| Plan announced | "I'll check your calendar, then draft three options" | Converts uncertain wait into a known, finite sequence |
| Step 1 in progress | "Checking calendar…" | Occupies attention, shows forward motion |
| Step transition | Checkmark or subtle animation on step 1, step 2 begins | Confirms progress is real, not stalled |
| Final step | "Drafting response…" | Signals proximity to completion |
This is also where doing visible work early pays off disproportionately: echoing the user's query back verbatim, or restating it in confirmed form, within the first 100-200ms, moves the perceived "start" of processing far earlier than the model's actual first token — addressing Maister's point that waits before a process visibly starts feel longest of all.
Optimistic UI: Borrowing Confidence From the Future
Optimistic UI renders the expected outcome of an action immediately, before the backend confirms it, then reconciles or rolls back if the real result differs. In traditional software this is a comment posting instantly while the network request completes behind it.
For AI products, optimistic UI is riskier because the "expected outcome" is often the thing that's genuinely uncertain — you don't know what the model will say until it says it. Legitimate optimistic-UI uses in AI interfaces are narrower than in CRUD apps:
- Rendering the user's own input instantly (their message appears immediately, not after a round trip).
- Pre-populating a UI shell for a known output shape (e.g., a table skeleton with column headers you already know, before rows are filled).
- Showing a cached or previous answer with a "refreshing…" label while a new one generates, rather than a blank state.
Where optimistic UI backfires badly: committing to a specific predicted answer before the model has produced it — showing a placeholder recommendation, then swapping it for a different real one — creates a visible contradiction that reads as the system being wrong, not just slow. This is a sharper version of a failure this blog has covered in designing for the hallucination failure mode: optimism about content (as opposed to optimism about shape) sets an expectation the system may not meet.
Skeleton Screens: Shape Before Substance
Skeleton screens show the layout structure of an eventual response — gray boxes where text, images, or cards will appear — before any content is ready. They work by giving the eye a stable shape to anchor on, reducing the layout shift and jarring "pop-in" that a blank-then-full transition causes.
Skeletons are well-suited to predictable output shapes: a list of search results, a dashboard of cards, a table with known columns. They're poorly suited to unpredictable output shapes, which describes a large share of generative AI responses — you often don't know if the answer will be one paragraph, a table, or a bulleted list until it's generated, and a skeleton that guesses wrong (three gray lines when the real answer is a table) creates its own small layout-shift surprise anyway.
Practical rule: use skeletons when the response container is fixed and only the content inside varies. Use streaming or progress narration when the container itself is unknown until generation completes.
When Each Technique Backfires — and How to Choose
No single technique is correct for every wait; the right choice depends on whether the output shape is known in advance and whether the process has genuine discrete steps to narrate. Choosing the wrong one can make a wait feel more uncertain, not less.
Use this as a quick decision aid rather than a strict algorithm — real products often combine two techniques for one wait (echo the query, then stream the answer, for instance):
| If your situation is… | Prefer… | Avoid… |
|---|---|---|
| Output shape is known (table, card list) | Skeleton screen | Streaming raw structure |
| Output shape is unknown until generated | Progress narration + streaming | Skeleton (guesses wrong) |
| Multi-step pipeline (retrieval → reasoning → generation) | Plan-then-narrate | A single generic spinner |
| Very short, near-instant responses | Instant render, no ceremony | Streaming (adds visible delay) |
| Long-tail worst case with no natural ceiling | All of the above, plus a defined timeout | An indefinite spinner with no exit |
The last row is the boundary case every one of these techniques eventually runs into: what happens when the wait genuinely does not end in a reasonable window. That's a distinct design problem from the ones above, and it deserves its own treatment — see the complete guide to UX of Failure for the fuller failure taxonomy this sits inside.
Where Perceived Performance Design Meets Its Limit
Perceived-performance techniques are designed to make a bounded wait feel shorter — they are not designed to handle the case where the wait has no reasonable bound at all, which is a different problem requiring an explicit failure boundary rather than more clever occupation. Streaming, narration, and skeletons all assume the process is progressing; none of them tell the user, or the system, when to stop assuming that.
This is the honest edge of what design-for-waiting can do. Once real latency crosses some threshold — a stuck tool call, a retrieval that returns nothing, a model stuck in a reasoning loop — the humane move isn't a more elaborate progress animation. It's a defined timeout with a clear, respectful exit: an apology, a retry option, a fallback path. Prodinja's UX of Failure Studio includes a Timeout pattern specifically for designing that boundary case — the moment perceived-performance work has to hand off to failure design. The two are complementary: perceived-performance techniques cover everything up to the boundary; the Timeout pattern is for designing the boundary itself, honestly, as a prototype-stage pattern you can walk through and adapt rather than a black box that decides for you.
Getting this handoff right also connects to how you frame the wait relative to what the user is actually trying to accomplish — which is where a customer journey emotion curve view is useful for spotting exactly where in a task a slow AI step causes the steepest emotional drop, so you know which waits deserve the most design investment first.
Key Takeaways
- Real latency and felt latency are different problems with different owners — engineering fixes one, design fixes the other, and only design is usually fixable this sprint.
- Occupied time feels short; uncertain time feels long — Maister's classic waiting-psychology principles, still the clearest lens for AI loading states decades later.
- Streaming works by giving users something to read, but backfires on structured output, mid-stream corrections, and very short responses.
- Progress narration must describe the real pipeline, not decorative theater — a fabricated step name is a trust cost, not a UX win.
- Skeleton screens fit known output shapes; unpredictable AI output shapes are better served by narration and streaming.
- Doing visible work early — echoing the query, stating a plan — moves the felt start of processing earlier, which matters disproportionately per Maister's own findings.
- Perceived-performance design has a limit: it shapes bounded waits, not unbounded ones. Unbounded waits need an explicit timeout and exit path as their own design problem.
Frequently Asked Questions
What is perceived performance in UX design?
Perceived performance is the subjective sense of how fast or slow an interface feels to a user, as distinct from its actual measured speed. It's shaped by occupied attention, visible progress, and certainty — not just wall-clock time — which is why two products with identical real latency can feel completely different to use.
Why does AI feel slower than other software even when it responds quickly?
AI responses violate users' calibrated expectations from decades of fast, predictable software, and their duration is often unpredictable and invisible until it's done. A wait that's both uncertain and unoccupied — the default for a plain spinner — reliably feels longer than one where users can see something happening, even at the same actual duration.
Does streaming always make AI responses feel faster?
Not always — streaming helps most for free-form prose where partial content is legible, but can hurt for structured output like code or JSON, where a partially-assembled block reads as broken rather than progressing. It can also add unnecessary perceived delay to answers that are naturally short enough to render instantly.
How long can an AI response take before users start abandoning it?
There's no universal number, but classic HCI response-time research (synthesized by groups like Nielsen Norman Group) puts roughly 1 second as where delay becomes noticeable and roughly 10 seconds as where attention drifts away entirely without some form of engagement. Perceived-performance techniques can extend that tolerance meaningfully, but they don't eliminate the need for a defined ceiling.
What's the difference between a skeleton screen and a loading spinner?
A skeleton screen shows the actual layout shape of the incoming content — gray boxes where text or cards will appear — while a spinner is a generic, content-agnostic animation. Skeletons reduce layout shift and give the eye something structural to anchor on, but they only work well when the output shape is predictable in advance.