It goes wrong before any state gets designed. Somebody asks how long it takes, somebody answers about three seconds, and everything downstream gets built for three seconds.
Three seconds is the median. The median is the case that never needed a design. What sets the experience is the realistic slow case, roughly the slowest response a normal user hits in a normal week, and engineering can produce that number in one query. Ask before the design review. It usually comes back one or two bands higher than the design side assumed, and a surface built two bands away from its real behavior is exactly what people mean when they call a product flaky.
Six bands.
Under 100ms feels instant. Adding an indicator here makes the product feel slower.
From 100ms to one second, keep the interface still. No layout movement, no spinner flashing in and out, no disabling the control that was just used. A loading state that appears and vanishes reads as a flicker, and flicker reads as a bug. The only requirement is that the control shows it received the input.
From one to ten seconds, the user is watching, and a generic spinner starts costing you because it says something is happening and nothing else. By second six they want to know what. Tie the indicator to the thing they asked for, in place rather than in a corner. Name the work in text. Keep the rest of the interface usable, since blocking the whole screen for eight seconds converts a wait into an outage. Stream the output if you can, because streaming turns a ten-second wait into a two-second wait plus reading time.
From ten seconds to two minutes, they will look away, so design for the return. Real progress means steps completed or a statement of what is being worked on, never an invented percentage. Give them a cancel and say what cancelling loses. The result survives navigation. If it lands while they are elsewhere, they get told.
Past two minutes it is a job, not a wait. Stop designing a loading state and design a lifecycle: closable without loss, listed with a status somewhere findable, completion through a channel they watch, failure through the same channel with the same prominence, partial results shown when partial results are useful.
Then the sixth band, agent work with no bounded end. Legibility is the problem there, not latency. One sentence answering what it is doing right now. A running account of what it has already done, which is also the undo surface. A summary waiting at the start of the next session, before anything else competes for attention. A stop control that is honest about what stopping leaves half finished.
Four rules across all six.
Never lie about progress. A bar that glides and then parks at ninety percent teaches people the interface is decorative, and that lesson generalizes to everything else you show them.
Name the work, not the mechanism. "Checking the last thirty days of usage" is information. "Querying warehouse" is engineering's mental model wearing a user's clothes.
A failed wait needs more design than a successful one. After twenty seconds, "something went wrong" is close to an insult. Say what failed, what survived, and what to do now.
Slow is survivable, unpredictable is not. Bring that one to any conversation about optimizing the median.
Copy is the deliverable here more than layout is. Every band above one second needs words, and if a generated surface in your product still says "Loading" then a decision has not been made, it has been deferred into a default.
This week: get the realistic slow case for your three most-used generated surfaces and put each in a band.
The six bands with required elements, the fill-in table, and the four rules are in Latency States by Duration Band. The argument is in Latency Is Interface.