New: Try Voli The Bear, Fast package manager (and not only) for Windows
Updated Jul 10, 2026 Edit on GitHub

What "Fast Enough" Means

So far we've treated speed as a number to push down. But here's the question that actually decides your work: down to what? There's no universal "fast." A weather forecast that updates once an hour is plenty fast. The same one-hour delay on a chat message is unusable garbage. Speed only means something next to a requirement - and next to a human who's waiting.

It's what keeps you from polishing a number forever, and from declaring victory while users are still suffering.

Fast is relative to a requirement

What it actually is. "Fast enough" is not a property of your code - it's a property of the job. The same response time can be excellent or terrible depending on what's expected:

  • A search box should feel instant - somewhere in the low tens to low hundreds of milliseconds, or it feels laggy.
  • A monthly report can take thirty seconds and nobody blinks - they kicked it off and went for coffee.
  • A background data import can run for an hour, because no human is sitting there watching it.

Same machine, same kind of work, wildly different bars. So before you optimize, you need the bar: what does this actually need to be? Without a target, "faster" has no finish line, and you'll keep running past it forever.

💡 Key point. Performance work has a destination, and the destination is a requirement, not "as fast as possible." "As fast as possible" is a budget with no bottom. The first question of any performance task is: fast enough for what?

Fast is relative to perception

The other half of "fast enough" is the human. Computers measure performance in numbers; people measure it in feeling, and the two don't map cleanly. A few things are worth knowing because they change what you optimize:

  • Below a certain point, faster stops mattering. Once a response feels instant to a person, shaving more milliseconds buys you nothing they'll notice. You can't perceive your way to caring about the difference between 20 ms and 10 ms on a button click.
  • Consistency beats raw speed. A response that's always a steady half-second feels better than one that's usually instant but occasionally hangs for three seconds. People forgive slow; they remember unpredictable. The hang is what sticks.

That second point is the bridge to the most important idea in this phase - because the hangs people remember aren't your average. They're your worst requests.

Tail latency: the slowest requests are what users feel

Here's the mistake that hides in plain sight. You measure your average response time, it's a comfortable 50 ms, and you call it fast. But the average is a liar. It blends your fast requests and your slow ones into a single number that describes nobody's actual experience.

What users feel is the tail - the slowest slice of requests. And it's not a rare edge case affecting strangers. The same user makes many requests, so over a session they're very likely to hit one of those slow ones. The hang they remember and complain about is sitting in your tail, completely invisible in your average.

This is why engineers measure performance in percentiles instead of averages.

📝 Terminology. A percentile tells you "X% of requests were at least this fast." The p50 (the median) is the request in the middle - half are faster, half are slower. The p99 is the slow tail: 99% of requests were faster than this, and the worst 1% were slower. People say "p99 latency" to mean "how bad are the slowest one-in-a-hundred requests."

   sort every request by how long it took, fastest to slowest:

   fast ████████████████████████████████████████░░░░  slow
        ▲                                  ▲       ▲
        p50                                p99     worst
        (the median, ~half)                (slow tail)
        the number that looks good         the number users actually feel

Why this matters. Your p50 can look fantastic while your p99 quietly ruins the experience for a real chunk of users on a regular basis. "We're fast - 50 ms average!" can hide a p99 of three full seconds. If you only ever watch the average, you're blind to exactly the requests that generate the complaints. The slowest requests are the ones that get talked about.

Watching the tail under realistic, sustained traffic - and catching it before your users do - is its own discipline. That's what Load and Performance Testing is for: it pushes real-shaped load through the system and reports the percentiles, so you find the three-second p99 in a test instead of in an angry message.

The cost and benefit of optimizing

The last piece ties the whole guide together. Optimization is never free. Every speedup costs something - your time, added complexity, more servers, code that's harder to read and change. So the real question is never "can I make this faster?" (you almost always can) but "is this speedup worth what it costs?"

Line the costs up against the benefit and the answer usually becomes obvious:

   BENEFIT of optimizing               COST of optimizing
   ─────────────────────               ──────────────────
   does it cross the requirement?      engineering time
   do users actually feel it?          added complexity / harder to change
   does it fix the tail (p99)?         more infrastructure to run & pay for
   does it unblock real work?          risk of new bugs
  • Pulling a three-second p99 down to under a second, when users are hitting it constantly? Almost always worth it - that's the requirement and the perception both, in the place people feel.
  • Shaving 5 ms off a button that already feels instant, by rewriting clean code into something nobody can maintain? Almost never worth it - you're paying real costs for a benefit no human can perceive.

⚠️ Knowing when to stop is a skill. Optimization can become a hobby that quietly hurts the project - you keep chasing numbers long past the point where anyone benefits, while features go unbuilt and the code grows more tangled with each "improvement." Once it's fast enough - it meets the requirement and feels good to users, tail included - stop. The next millisecond is almost never where your time should go.

Why this saves you later. Put the three rules together and you have a complete way to reason about any "make it faster" request. First (Phase 1): which number - latency or throughput? Second (Phase 2): measure, and fix the actual bottleneck. Third (this phase): measure against a requirement, watch the tail not the average, and stop when it's worth-it done. That's not a trick or a tool. It's a way of thinking that turns "performance" from a scary, bottomless word into a set of concrete, answerable questions.

Recap

  1. Fast is relative to a requirement - there's no universal "fast." The first question is always fast enough for what?
  2. Fast is relative to perception - past "feels instant," more speed buys nothing; and consistency beats raw speed because people remember the hangs.
  3. Tail latency is what users feel. The average hides your slowest requests; measure percentiles (p50, p99) and care about the tail.
  4. Optimization has a cost. Weigh it against the benefit, and stop when it's fast enough - the next millisecond is rarely worth it.

That's the "A" of performance. You now have the mental model: the two numbers, the rule of measuring, and the meaning of "enough." When you're ready for the skills this sets up, the related guides below are the natural next steps.


Related guides


← Phase 2: Measure Before You Optimize · Guide overview →

Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.

Check your understanding 3 questions

1. What does fast enough actually depend on?

2. Why do you measure percentiles (like p99) instead of the average?

3. When should you stop optimizing?