Latency is a product feature.
Nobody specs it, everybody churns on it.
Nobody writes response time into the spec, and everybody churns on it. Why latency is a product decision, not an infrastructure afterthought.
No product spec I've ever reviewed had a line item for response time. Plenty of those same products have a churn chart with a bend in it nobody can quite explain. Here's the uncomfortable part: those two facts are usually the same fact, and almost nobody makes that connection until it's already cost them users.
01 · Users don't file a ticket about slow
A broken button gets reported. A slow one gets abandoned in silence. Users rarely complain about latency directly, they just come back less, and by the time that shows up in a retention dashboard it is weeks removed from the architectural decision that caused it. That lag is exactly why latency stays unmanaged: the feedback loop is too slow to feel like a fire.
Roughly 200 milliseconds is where a response stops feeling instant and starts feeling like waiting. Most teams don't know how many of those 200 milliseconds their own product has already spent before a user even notices.
“Nobody churns because a feature was missing. Plenty of people churn because the product felt like it was thinking too hard.”
02 · Where the budget actually goes
Latency is spent in small, individually defensible decisions: a synchronous call to a service that could have streamed a partial result, a model chosen because it scored well on a benchmark and never once on p95 (the response time 95% of real requests fall under, the number that describes what most users actually feel), an extra network hop added for a clean abstraction, a cache that got skipped because the data might be stale. None of those decisions look wrong in a code review. Stacked, they are the product.
$ trace request --id=req_8841 --breakdownauth check ............... 42msuser profile lookup ....... 118msinventory service ......... 96mspricing service (sync) .... 310msrecommendation model ...... 890msrender + hydrate .......... 140mstotal ..................... 1,596ms# nobody owns this number. it just happened.
That trace is a composite of the kind we see constantly: no single service is disastrously slow, but two of six steps run synchronously when they could run in parallel or stream, and the recommendation call is on the critical path for a page that didn't need it there. Nobody chose 1.6 seconds. Six people each chose something smaller, and the sum was nobody's decision to make.
03 · A budget, not a hope
The teams that stay fast treat latency like any other requirement with a number attached: a target measured at p95 and p99 (the slowest 1% of requests, the ones that quietly define your worst users' experience) in production, not an average in staging, owned by a specific person who is accountable when it slips. Everything else follows from that one decision to make it measurable and someone's job.
An average hides the damage. If your average is 400ms and your p99 is 4 seconds, one user in a hundred is having a genuinely bad time on every single visit, and your dashboard looks fine the whole time.
04 · Four things that actually move the number
- 01Measure p95 and p99 in production, not average in staging. Staging traffic is polite. Production traffic is not. Averages flatter you; tail percentiles tell you the truth about your worst-case user.
- 02Get work off the critical path. Anything that doesn't block the response the user is waiting for, logging, non-essential enrichment, secondary model calls, should run after the response, not before it.
- 03Cache the boring 80%. Most requests aren't novel. A cache in front of the predictable majority buys you latency budget to spend on the genuinely dynamic minority.
- 04Make regressions loud in CI, not quiet in prod. A latency budget with no enforcement is a wish. Gate the build on it the same way you'd gate on a failing test, and a regression gets caught before it ships, not after churn tells you.
// we've inherited systems where every individual service met its own SLA and the product still felt slow. the SLAs were measuring the wrong thing: each service in isolation, never the path a real user actually walks.
05 · Why this is a product conversation, not an infra ticket
Framing latency as an infrastructure concern is how it ends up owned by nobody: infra optimizes what it can measure, which is usually server-side time, while the user experiences everything, including the parts product and design control. Latency has to sit in the same room as the roadmap, because the fix is as often "stream this instead of blocking on it" or "don't call the model on this screen at all" as it is a database index.
So put a number in the spec. Not "fast," a number: p95 under some real, tested threshold, owned by a name. It won't feel urgent the day you write it down. It will feel very urgent the day you don't, and a slow bleed of users you'll never get a ticket about goes looking for something that feels instant instead.
$ end of file · written by flux/jeswin · 2026-08-10